[英]How To Group Objects In Array By Unique Properties in Javascript?
[英]JavaScript: How to Group Array of Objects with Nested Properties?
我有這個對象數組:
[
{
"date": "08/08/2022",
"name": "Swordsman",
"items": [
{
"item_id": 1,
"item": {
"item_name": "Item 1",
},
"count": 1
}
]
},
{
"date": "08/08/2022",
"name": "Swordsman",
"items": [
{
"item_id": 1,
"item": {
"item_name": "Item 1",
},
"count": 2
},
{
"item_id": 2,
"item": {
"item_name": "Item 2",
},
"count": 1
}
]
}
]
我想要實現的是按日期、名稱和項目數進行分組。 期望的結果是:
[
{
"date": "08/08/2022",
"name": "Swordsman",
"items": [
{
"item_id": 1,
"name": "Item 1",
"count": 3
},
{
"item_id": 2,
"name": "Item 2",
"count": 1
}
]
}
]
如果日期相同但名稱不同,例如:
[
{
"date": "08/08/2022",
"name": "Swordsman",
"items": [
{
"item_id": 1,
"item": {
"item_name": "Item 1",
},
"count": 1
}
]
},
{
"date": "08/08/2022",
"name": "Swordsman",
"items": [
{
"item_id": 1,
"item": {
"item_name": "Item 1",
},
"count": 2
},
{
"item_id": 2,
"item": {
"item_name": "Item 2",
},
"count": 1
}
]
},
{
"date": "08/08/2022",
"name": "Archer",
"items": [
{
"item_id": 1,
"item": {
"item_name": "Item 1",
},
"count": 2
},
{
"item_id": 2,
"item": {
"item_name": "Item 2",
},
"count": 1
}
]
}
]
期望的結果是:
[
{
"date": "08/08/2022",
"name": "Swordsman",
"items": [
{
"item_id": 1,
"name": "Item 1",
"count": 3
},
{
"item_id": 2,
"name": "Item 2",
"count": 1
}
]
},
{
"date": "08/08/2022",
"name": "Archer",
"items": [
{
"item_id": 1,
"name": "Item 1",
"count": 2
},
{
"item_id": 2,
"name": "Item 2",
"count": 1
}
]
}
]
我嘗試過使用 lodash 和 array reduce 方法,但仍然無法獲得所需的結果:
const groups = data.reduce((groups, data) => {
const date = data.date;
if (!groups[date]) {
groups[date] = [];
}
groups[date].push(data);
return groups;
}, {});
const groupArrays = Object.keys(groups).map((date) => {
return {
date,
items: groups[date]
};
});
如何實現這一目標? 需要你的投入。 謝謝!
您可以通過以下方式實現:
const arr = [ { date: '08/08/2022', name: 'Swordsman', items: [ { item_id: 1, item: { item_name: 'Item 1', }, count: 1, }, ], }, { date: '08/08/2022', name: 'Swordsman', items: [ { item_id: 1, item: { item_name: 'Item 1', }, count: 2, }, { item_id: 2, item: { item_name: 'Item 2', }, count: 1, }, ], }, { date: '08/08/2022', name: 'Archer', items: [ { item_id: 1, item: { item_name: 'Item 1', }, count: 2, }, { item_id: 2, item: { item_name: 'Item 2', }, count: 1, }, ], }, ]; function addItemsToNewArrFromOld(oldItems, newItemsToAdd) { newItemsToAdd.forEach((o) => { const { item_id, count, item: { item_name: item }} = o; const itemInOldItems = oldItems.find((obj) => obj.item_id === o.item_id); if (itemInOldItems) itemInOldItems.count += o.count; else oldItems.push({ item_id, count, item }); }); } const map = new Map(); arr.forEach(({ date, name, items }) => { const key = `${date}-${name}`; if (map.has(key)) { const objForKeyFound = map.get(key); addItemsToNewArrFromOld(objForKeyFound.items, items); } else { map.set(key, { date, name, items: items.map(({ item_id, item, count }) => ({ item_id, count, item: item.item_name })), }); } }); const result = [...map.values()]; console.log(result);
Array#reduce
迭代列表,同時更新Map
,其中key
為<date>-<name>
且value
分組的 object (具有此鍵的所有items
)。Array#map
遍歷上述分組對象。 對於每個 object,我們需要在更新count
時按item_id
對其items
進行分組。 const groupByDateAndName = arr => [... arr.reduce((map, { date, name, items = [] }) => { const key = `${date}-${name}`; const { items: prevItems = [] } = map.get(key)?? {}; map.set( key, { date, name, items: [...prevItems, ...items.map(({ item_id, item, count }) => ({ item_id, count, name: item.item_name })) ] } ); return map; }, new Map).values() ]; const groupItemsById = arr => arr.map(e => { const items = [... e.items.reduce((map, { item_id, name, count }) => { const { count: prevCount = 0 } = map.get(item_id)?? {}; map.set(item_id, { item_id, name, count: prevCount + count }) return map; }, new Map).values() ] return {...e, items }; }); const group = (arr = []) => { const list = groupByDateAndName(arr); return groupItemsById(list); } const arr = [ { "date": "08/08/2022", "name": "Swordsman", "items": [ { "item_id": 1, "item": { "item_name": "Item 1" }, "count": 1 } ] }, { "date": "08/08/2022", "name": "Swordsman", "items": [ { "item_id": 1, "item": { "item_name": "Item 1" }, "count": 2 }, { "item_id": 2, "item": { "item_name": "Item 2" }, "count": 1 } ] }, { "date": "08/08/2022", "name": "Archer", "items": [ { "item_id": 1, "item": { "item_name": "Item 1" }, "count": 2 }, { "item_id": 2, "item": { "item_name": "Item 2" }, "count": 1 } ] } ]; console.log( group(arr) );
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.