0

I need to merge a list of array of objects by a key. I tried to find materials online but ended up only on merging 2 array of objects.

But I have multiple array of objects in an array.

response = [
    [
        {
            "topic": "Topic 1",
            "avgwk38": 5
        },
        {
            "topic": "Topic 2",
            "avgwk38": 86
        },
        {
            "topic": "Topic 3",
            "avgwk38": 6
        }
    ],
    [
        {
            "topic": "Topic 1",
            "avgwk39": 25
        },
        {
            "topic": "Topic 2",
            "avgwk39": 32
        },
        {
            "topic": "Topic 3",
            "avgwk39": 4
        }
    ]
]

Here is my expected result.

[
    {
        "topic": "Topic 1",
        "avgwk38": 5,
        "avgwk39": 25
    },
    {
        "topic": "Topic 2",
        "avgwk38": 86,
        "avgwk39": 32
    },
    {
        "topic": "Topic 3",
        "avgwk38": 6,
        "avgwk39": 4
    }
]

Please help me out to resolve this.

3

2 Answers 2

1

You could flatten your array and reduce values.

response.flat().reduce((acc, value) => {
  let existingValueIndex = acc.findIndex(obj => obj.topic === value.topic);
  if (existingValueIndex === -1) {
    acc.push({ ...value });
    return acc;
  }

  acc[existingValueIndex] = {
    ...acc[existingValueIndex],
    ...value,
  };
  return acc;
}, []);

It's not really efficient if you have big arrays. You can also use a Set to keep track on Topic names and prevent searching in the array for each iteration.

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

1 Comment

Thank you @PAG this is working like a charm. I have only small arrays, as this is a monthly view with each week's average value.
1

Here is another way of solving this,
Making an object of topics with a unique topic, which contains the properties of each topic item.

Finally using Object.values() to make this an array.

const response = [
    [
        {
            "topic": "Topic 1",
            "avgwk38": 5
        },
        {
            "topic": "Topic 2",
            "avgwk38": 86
        },
        {
            "topic": "Topic 3",
            "avgwk38": 6
        }
    ],
    [
        {
            "topic": "Topic 1",
            "avgwk39": 25
        },
        {
            "topic": "Topic 2",
            "avgwk39": 32
        },
        {
            "topic": "Topic 3",
            "avgwk39": 4
        }
    ]
]

const obj = response.flat().reduce((acc, curr) => {
  if(!acc[curr.topic]) {
    acc[curr.topic] = {
      ...curr
    }
  } else {
    acc[curr.topic] = {
      ...acc[curr.topic],
      ...curr
    }
  }

  return acc;
}, {});

console.log(Object.values(obj));

1 Comment

Thanks mate @zb22 . Spread operator acts as a super power to JS

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.