0

I have 2 arrays which is contains same id with different value (inside selected) My goal is to merge both become 1 array.

When I use spread operator like this:

data = [
  ...data.filter(
    (a) => a.id === newData.id
  ),
  newData];

It comes the data being override

First array

[
 {
    id: "A527CFFE",
    selected: [
      {
        itemId: "A1",
        text: "Selected 1"
      }
    ]
 }
]

Second array

[
 {
    id: "A527CFFE",
    selected: [
      {
        itemId: "A2",
        text: "Selected 2"
      }
    ]
 }
]

How can I make both of arrays become 1 ? the expected result:

[
 {
    id: "A527CFFE",
    selected: [
      {
        itemId: "A1",
        text: "Selected 1"
      },
      {
        itemId: "A2",
        text: "Selected 1"
      }
    ]
 }
]

What am I doing wrong in the above?

3
  • Do both arrays always have same items (same ids)? Commented Jul 21, 2022 at 15:09
  • Hi @ulou yes it always have a same id Commented Jul 21, 2022 at 17:07
  • For similar (even more complex) tasks of the ever same underlying problem/pattern of "grouping, merging and aggregating" one, for the latter, might consider a generic approach in combination with custom provided functions for each ... group, merge and aggregate. Commented Jul 21, 2022 at 19:25

2 Answers 2

2

You can use Array.reduce() to combine the two arrays into one.

We start by concatenating and then grouping by id. For each item with the same ids we combine the selected arrays.

const arr1 = [ { id: "A527CFFE", selected: [ { itemId: "A1", text: "Selected 1" } ] } ]
const arr2 = [ { id: "A527CFFE", selected: [ { itemId: "A2", text: "Selected 2" } ] } ]

const result = Object.values([...arr1, ...arr2].reduce((acc, { id, selected }) => { 
    acc[id] = acc[id] || { id, selected: [] };
    acc[id].selected = [...acc[id].selected, ...selected];
    return acc;
}, {}));

console.log('Result:', result);
.as-console-wrapper { max-height: 100% !important; }

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

2 Comments

A better-written answer and better code.
Thanks !, this is what I need, I managed to use this with some modification and my issue has been resolved. Again many thanks !
1

const arrA=[{id:"A527CFFE",selected:[{itemId:"A1",text:"Selected 1"}]}]
const arrB=[{id:"A527CFFE",selected:[{itemId:"A2",text:"Selected 2"}]}]

const res = arrA.map(e => { // map all items of first array
  const found = arrB.find(x => x.id === e.id) // find item in second array with same id
  return found // check if item has been found in second array
      ? {id: e.id, selected: [...e.selected, ...found.selected]} // if yes, merged selected 
      : e // if no, return only item from first array         
})

console.log(res)
.as-console-wrapper { max-height: 100% !important; top: 0; } /* ignore this */

1 Comment

Thank you for your answer ! I managed to fix the problem using part of your code :)

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.