2016-12-11 2 views
0

У меня есть массив объектов, каждый из которых содержит две категории, одна из которых представляет собой группу.Фильтрация массива объектов по полю

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

Я ищу, чтобы создать ответ JSON, который классифицировал их по группам.

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

На данный момент я достиг этого первой итерации и создания набора всех вовлеченных групп, а затем итерация снова и группируя их соответствующим образом. Мне было интересно, был ли более лаконичный способ сделать это, возможно, используя некоторые новые операторы, введенные в ES6.

+4

В ES6 нет ничего конкретного для такого преобразования данных. Вы можете принять решение ES5 и сделать его более кратким и читаемым с помощью функций стрелок, операторов распространения, деконструкции и, возможно, даже метода 'Array # find'. –

+0

Этот вопрос слишком широк, потому что эта задача может быть выполнена множеством разных способов. Попробуйте найти решение самостоятельно, и если вы столкнулись с какой-либо конкретной проблемой, спросите. –

+0

Я упомянул, что у меня было решение, просил здесь посмотреть, есть ли у него другой подход ... – FredLoh

ответ

3

Итерации, используя Array#reduce, и собирать предметы по группам в Map. Используйте распространение для преобразования Map#values обратно в массив:

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

Вы не указали круглые скобки для «новой карты»? Кроме того, я считаю, что лучше использовать 'Array.from()' вместо синтаксиса распространения, чтобы преобразовать итерируемый объект в массив, потому что он более явный. –

+0

Конечно. Они [необязательно] (http://stackoverflow.com/a/3034952/5157454). Мне нравится 'Array.from()', но с расширением вы можете видеть массив, поэтому я не уверен, что более явное. –

+0

@OriDrori, в чем причина новой карты в конце? Я слежу за этим до этого момента, а затем теряюсь. Зачем это нужно? – FredLoh

0

Я не знаю есть какой-то новый оператор или функция массива, чтобы сделать это легче введенный в ES6, однако вы могли бы должен иметь возможность сделать это за одну итерацию:

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}); 
    } 
}