I have this array of objects:
[
{
"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
}
]
}
]
What I wanted to achieve is to group by date , name and the number of items . The desired result would be:
[
{
"date": "08/08/2022",
"name": "Swordsman",
"items": [
{
"item_id": 1,
"name": "Item 1",
"count": 3
},
{
"item_id": 2,
"name": "Item 2",
"count": 1
}
]
}
]
If it has the same date but different name like:
[
{
"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
}
]
}
]
The desired result would be:
[
{
"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
}
]
}
]
I've tried using lodash and array reduce method but still unable to get the desired result:
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]
};
});
How to achieve this one? Need your inputs. Thanks!
You can achieve this as:
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
, iterate over the list while updating a Map
where the key
is <date>-<name>
and the value
is the grouped object (having all items
of this key).Array#map
, iterate over the above grouped objects. For each object, we need to group its items
by item_id
while updating the count
. 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) );
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.