2017-07-28 1 views
0

Ich bin neu in Javascript, und ich habe JSON-Array, das einige Nachschlüssel wie unten enthält:Finden Maximalwert von JSON-Objekte aus dem Array und kombiniere sie

var connections = [ 

    { 
     "source":"l1", 
     "target":"l2", 
     "metrics": { "normal":20 }, 
     "metadata": { "streaming": 1 } 
    }, 
    { 
     "source":"l2", 
     "target":"l3", 
     "metrics": { "normal":30 }, 
     "metadata": { "streaming": 1 } 
    }, 

    { 
     "source":"l2", 
     "target":"l3", 
     "metrics": { "normal":25 }, 
     "metadata": { "streaming": 1 } 
    }, 
    { 
     "source":"l3", 
     "target":"l4", 
     "metrics": { "normal":24 }, 
     "metadata": { "streaming": 1 } 
    }, 
    { 
     "source":"l3", 
     "target":"l4", 
     "metrics": { "normal":21 }, 
     "metadata": { "streaming": 1 } 
    }, 
    { 
     "source":"l3", 
     "target":"l4", 
     "metrics": { "normal":20 }, 
     "metadata": { "streaming": 1 } 
    }, 


] 

Jetzt möchte ich doppelte JSON fusionieren, die denselben Wert hat von "source" und "target" und Schlüssel "normal" sollte das Maximum der gleichen Quelle und Ziel sein. So ist die Antwort für gegebenes Beispiel wird sein:

var answer =[ 
{ 
      "source":"l1", 
      "target":"l2", 
      "metrics": { "normal":20 }, 
      "metadata": { "streaming": 1 } 
     }, 
     { 
      "source":"l2", 
      "target":"l3", 
      "metrics": { "normal":30 }, 
      "metadata": { "streaming": 1 } 
     }, 
     { 
      "source":"l3", 
      "target":"l4", 
      "metrics": { "normal":24 }, 
      "metadata": { "streaming": 1 } 
     }, 

] 

Dies ist nur ein Beispiel Objekt, das es auf mit verschiedenen Objekten geht. Ich weiß nicht, wie ich dieses Problem lösen kann, Ich denke, Unterstreichung oder Lodash kann leicht sein, dieses Problem zu lösen, aber jeder knid der Lösung wird akzeptiert.

Antwort

1

Verwenden Sie _.groupBy(), um Objekte nach Quelle und Ziel zu sammeln. Verwenden Sie _.map() und Array # reduce, um den Wert normal in jeder Gruppe zu ermitteln.

var connections = [{"source":"l1","target":"l2","metrics":{"normal":20},"metadata":{"streaming":1}},{"source":"l2","target":"l3","metrics":{"normal":30},"metadata":{"streaming":1}},{"source":"l2","target":"l3","metrics":{"normal":25},"metadata":{"streaming":1}},{"source":"l3","target":"l4","metrics":{"normal":24},"metadata":{"streaming":1}},{"source":"l3","target":"l4","metrics":{"normal":21},"metadata":{"streaming":1}},{"source":"l3","target":"l4","metrics":{"normal":20},"metadata":{"streaming":1}}]; 
 

 
var result = _(connections) 
 
    .groupBy(function(o) { // group by source and target 
 
    return o.source + '-' + o.target; 
 
    }) 
 
    .map(function(arr) { // map the groups to values 
 
    return arr.reduce(function(max, o) { // get the object with the hight normal in each group 
 
     return max.metrics.normal > o.metrics.normal ? max : o; 
 
    }); 
 
    }) 
 
    .value(); 
 

 
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>

0

Sie könnten das Array in ein neues Array reduzieren, basierend auf dem Ziel und der Quelle gleich ist, und dann überprüft, ob Kennzahlen mehr als der zuvor gespeicherte Wert

var connections = [ 
 
    {"source": "l1", "target": "l2", "metrics": {"normal": 20}, "metadata": {"streaming": 1} }, 
 
    {"source": "l2", "target": "l3", "metrics": {"normal": 30}, "metadata": {"streaming": 1} }, 
 
    {"source": "l2", "target": "l3", "metrics": {"normal": 25}, "metadata": {"streaming": 1} }, 
 
    {"source": "l3", "target": "l4", "metrics": {"normal": 24}, "metadata": {"streaming": 1} }, 
 
    {"source": "l3", "target": "l4", "metrics": {"normal": 21}, "metadata": {"streaming": 1} }, 
 
    {"source": "l3", "target": "l4", "metrics": {"normal": 20}, "metadata": {"streaming": 1} } 
 
] 
 

 
var res = connections.reduce((a,b) => { 
 
    let i = a.findIndex(item => item.target === b.target && item.source === b.source); 
 
    if (i===-1) { 
 
     a.push(b); 
 
    } else if (a[i].metrics.normal < b.metrics.normal) { 
 
     a[i] = b; 
 
    } 
 
    return a; 
 
}, []); 
 

 
document.body.innerHTML = '<pre>' + JSON.stringify(res,0,4) + '</pre>'

1

Sie können ein Objekt als eine Karte verwenden, die mit source + target als Schlüssel und das Objekt von connections als Wert, die, die mit dem höchsten Metrik für jede Kombination von source + target keeping:

var connections = [ 
 
    {"source": "l1", "target": "l2", "metrics": {"normal": 20}, "metadata": {"streaming": 1} }, 
 
    {"source": "l2", "target": "l3", "metrics": {"normal": 30}, "metadata": {"streaming": 1} }, 
 
    {"source": "l2", "target": "l3", "metrics": {"normal": 25}, "metadata": {"streaming": 1} }, 
 
    {"source": "l3", "target": "l4", "metrics": {"normal": 24}, "metadata": {"streaming": 1} }, 
 
    {"source": "l3", "target": "l4", "metrics": {"normal": 21}, "metadata": {"streaming": 1} }, 
 
    {"source": "l3", "target": "l4", "metrics": {"normal": 20}, "metadata": {"streaming": 1} } 
 
]; 
 

 
var map = {}; 
 
connections.forEach((connection) => { 
 
    var mapKey = connection.source + "/" + connection.target; 
 
    answerConnection = map[mapKey]; 
 

 
    if (!answerConnection || answerConnection.metrics.normal < connection.metrics.normal) 
 
    map[mapKey] = connection; 
 
}); 
 

 
var answer = Object.values(map); 
 

 
console.log(answer);

Verwandte Themen