Reputation: 11
I have an array that I like to group by the ID, but pushing all the different elements in the arrays in the result.
let data = [
{ id: "1", elements: ["a","b"], files: [] },
{ id: "1", elements: ["a","b"], files: [] },
{ id: "2", elements: ["a","b","c"],
files: [
{ name: "test1",
extension: "pdf"
},
{ name: "test2",
extension: "pdf"
}
]
},
{ id: "2", elements: ["a","b","c"],
files: [
{ name: "test3",
extension: "png"
},
{ name: "test4",
extension: "png"
},
{ name: "test5",
extension: "pdf"
}
]
},
{ id: "2", elements: ["a","b","c"], files: []
}
];
I want a result like
result =
[
{
"id": "1", "elements": [ "a", "b" ], "files": [] },
{
"id": "2", "elements": [ "a", "b", "c" ],
"files": [
{ "name": "test1", "extension": "pdf" },
{ "name": "test2", "extension": "pdf" },
{ "name": "test3", "extension": "png" },
{ "name": "test4", "extension": "png" },
{ "name": "test5", "extension": "pdf" },
]
}
]
How it is possible with lodash or any other process getting the desire output
Upvotes: 1
Views: 67
Reputation: 30685
You can use Array.reduce()
to group the items by id
.
This creates an object with a property for each id, we can then use Object.values()
to get the result as an array.
For the elements
array, we'll also use a Set
to ensure we don't duplicate elements. We only want ['a','b'] rather than ['a','b','a','b'] for example.
let data = [ { id: "1", elements: ["a","b"], files: [] }, { id: "1", elements: ["a","b"], files: [] }, { id: "2", elements: ["a","b","c"], files: [ { name: "test1", extension: "pdf" }, { name: "test2", extension: "pdf" } ] }, { id: "2", elements: ["a","b","c"], files: [ { name: "test3", extension: "png" }, { name: "test4", extension: "png" }, { name: "test5", extension: "pdf" } ] }, { id: "2", elements: ["a","b","c"], files: [] } ];
const result = Object.values(data.reduce((acc, { id, elements, files }) => {
acc[id] = acc[id] || { id, elements: [], files: []};
// Use a Set to avoid duplicates...
acc[id].elements = [...new Set([...elements, ...acc[id].elements])];
acc[id].files.push(...files);
return acc;
}, {}));
console.log('Result:', result)
.as-console-wrapper { max-height: 100% !important; }
Upvotes: 1