0

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.

1
  • @Nitheesh I have no code as I have no clue how to start with tackling this issue. Commented Nov 17, 2021 at 9:57

1 Answer 1

1

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 and label
  • It there is a node with same id and label, push the current item to the items array of that node else insert a new node to the accumulator with id, label and items

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

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you Nitheesh, it works. I thought about array.reduce(), but never understood it really well.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.