2016-12-11 3 views
0

Ich habe ein Array von Objekten, die jeweils zwei Kategorien enthalten, eine dieser Kategorien repräsentiert eine Gruppe.Filtern eines Arrays von Objekten durch ein Feld

[ 
    { 
    "uuid": 123, 
    "group": "test_group" 
    }, 
    { 
    "uuid": 321, 
    "group": "test_group" 
    }, 
    { 
    "uuid": 432, 
    "group": "test_group2" 
    } 
] 

Ich suche eine JSON-Antwort zu erzeugen, die sie durch ihre Gruppen eingeteilt hat.

{ 
    "objects": [ 
    { 
     "group": "test_group", 
     "items": [ 
     { 
      "uuid": 123 
     }, 
     { 
      "uuid": 321 
     } 
     ] 
    }, 
    { 
     "group": "test_group2", 
     "items": [ 
     { 
      "uuid": 432 
     } 
     ] 
    } 
    ] 
} 

Im Moment habe ich dies habe zuerst erreicht, indem über laufen und eine Reihe von allen beteiligten Gruppen zu schaffen, und dann wieder Iterieren und sie entsprechend zu gruppieren. Ich habe mich gefragt, ob es eine prägnantere Möglichkeit gibt, dies zu tun, vielleicht mit einigen der neuen, in ES6 eingeführten Operatoren.

+4

Es gibt nichts bestimmtes in ES6 für diese Art der Datenumformung. Sie können eine ES5-Lösung verwenden und sie übersichtlich und lesbar machen, indem Sie Pfeilfunktionen, Spread-Operatoren, Dekonstruktion und vielleicht sogar die 'Array # find'-Methode verwenden. –

+0

Diese Frage ist zu weit gefasst, da diese Aufgabe auf viele verschiedene Arten gelöst werden kann. Versuchen Sie, selbst eine Lösung zu finden, und fragen Sie, wenn Sie auf ein bestimmtes Problem stoßen. –

+0

Ich erwähnte, dass ich eine Lösung hatte, fragte hier um zu sehen, ob jemand eine andere Einstellung dazu hatte ... – FredLoh

Antwort

3

Iterieren Sie mit Array#reduce, und sammeln Sie die Elemente nach Gruppe in eine Map. Verwenden Ausbreitung der Map#values zurück in einem Array zu konvertieren:

const data = [ 
 
    { 
 
    "uuid": 123, 
 
    "group": "test_group" 
 
    }, 
 
    { 
 
    "uuid": 321, 
 
    "group": "test_group" 
 
    }, 
 
    { 
 
    "uuid": 432, 
 
    "group": "test_group2" 
 
    } 
 
]; 
 

 
const result = [...data.reduce((hash, { uuid, group }) => { 
 
    const current = hash.get(group) || { group, items: [] }; 
 
    
 
    current.items.push({ uuid }); 
 
    
 
    return hash.set(group, current); 
 
}, new Map).values()]; 
 

 
console.log(result);

+0

Haben Sie die Klammern für 'neue Map' absichtlich weggelassen? Außerdem denke ich, dass es besser ist, 'Array.from()' anstelle der Spreadsyntax zu verwenden, um ein iterbares Objekt in ein Array zu konvertieren, weil es auf diese Weise expliziter ist. –

+0

Natürlich. Sie sind [optional] (http://stackoverflow.com/a/3034952/5157454). Ich mag 'Array.from()', aber mit Spread können Sie das Array sehen, also bin ich mir nicht sicher, was expliziter ist. –

+0

@OriDrori Was ist der Grund für die neue Map am Ende? Ich folge es bis zu diesem Punkt und dann verloren. Warum wird es benötigt? – FredLoh

0

Ich weiß nicht, von dort ein paar neuen Operator oder eine Array-Funktion ist dies einfacher in ES6 eingeführt zu machen, aber könnten Sie sollte es in einer einzigen Iteration tun können:

var arrayLength = myArray.length; 
var response = {objects: []}; 
var groupIndex = {}; 

for (var i = 0; i < arrayLength; i++) { 
    let group = myArray[i].group; 
    if (!groupIndex.hasOwnProperty(group)) { 
    groupIndex[group] = groupIndex.length; 
    response.objects.push({ 
     group: group, 
     items: [ 
     {uuid: myArray[i].uuid} 
     ] 
    } 
    else { 
    let index = groupIndex[group]; 
    response.objects[index].items.push({uuid: myArray[i].uuid}); 
    } 
} 
Verwandte Themen