This is my example:
{
id: 'productId',
label: 'productLabel',
items: productSizes.map( productSize => {
return {
id: productSize.groupId,
label: productSize.groupId.split('-')[0],
items: productSize.size,
}
}),
}
This would result in something like this with our data:
{
id: 'productId',
label: 'productLabel'
items: [
{id: 'productA-11', label: 'productA', items: {width: 100, height: 100}},
{id: 'productA-11', label: 'productA', items: {width: 150, height: 150}},
{id: 'productA-11', label: 'productA', items: {width: 200, height: 200}},
{id: 'productB-22', label: 'productB', items: {width: 100, height: 100}},
]
}
But I would like to get something like this:
{
id: 'productId',
label: 'productLabel'
items: [
{id: 'productA-11', label: 'productA', items: [ {width: 100, height: 100}, {width: 150, height: 150}, {width: 200, height:200}],
{id: 'productB-22', label: 'productB', items: [{width: 100, height: 100}],
]
}
Not sure if I described my problem well with words, but I would like to somehow flatten the inner property items
, so that sizes of the SAME productId
would be merged into a single array.
CodePudding user response:
Array.reduce
will help you
Logic
- Loop throughthe
items
array of your object. - Check if the accumulator of the reducer already have an item with same
id
andlabel
- It there is a node with same
id
andlabel
, push the current item to theitems
array of that node else insert a new node to the accumulator withid
,label
anditems
Working Fiddle
const data = {
id: 'productId',
label: 'productLabel',
items: [
{ id: 'productA-11', label: 'productA', items: { width: 100, height: 100 } },
{ id: 'productA-11', label: 'productA', items: { width: 150, height: 150 } },
{ id: 'productA-11', label: 'productA', items: { width: 200, height: 200 } },
{ id: 'productB-22', label: 'productB', items: { width: 100, height: 100 } },
]
};
const { id, label } = data;
const items = data.items.reduce((acc, curr) => {
const node = acc.find(item => item.id === curr.id && item.label === curr.label);
if (node) {
node.items.push(curr.items);
} else {
acc.push({
id: curr.id,
label: curr.label,
items: [curr.items]
})
}
return acc;
}, [])
const output = {
id,
label,
items,
}
console.log(output);
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>