Search code examples
javascriptarraysecmascript-6

Merge two arrays into one with unique values, and change the id key


I have two arrays of objects, the objects within these arrays have a slightly different keys but share same id.

What i am trying to do is merge these two arrays into one that contains all the elements from both without duplicates.

array one:

[
   {id: 'ABC_123', value: 10, label: 'tree', level: 'mid'},
   {id: 'ABC_456', value: 11, label: 'grass', level: 'top'}
];

array two:

[
   {levelId: 'ABC_123', value: 10, label: 'tree', level: 'mid'},
   {levelId: 'ABC_456', value: 11, label: 'grass', level: 'top'},
   {levelId: 'ABC_789', value: 11, label: 'bush', level: 'low'}
];

I want to bring all the new elements from array two into array one in this example i want element with levelId: 'ABC_789 to move into array one and change the levelId key into id:

result:

[
       {id: 'ABC_123', value: 10, label: 'tree', level: 'mid'},
       {id: 'ABC_456', value: 11, label: 'grass', level: 'top'}
       {id: 'ABC_789', value: 11, label: 'bush', level: 'low'}

]

I have tried mapping over them matching the id's and creating new array but I cant get the desired result


Solution

  • You need to loop over both structures.

    I am using reduce as a loop structure and find acts as one too.

    You essentially want to look through the possible new values and determine if it exists already in the first array. If it doesn't exist then push its value into array 1.. in this case a new object structure.

    Here is a rough solution:

    let arr1 = [
       {id: 'ABC_123', value: 10, label: 'tree', level: 'mid'},
       {id: 'ABC_456', value: 11, label: 'grass', level: 'top'}
    ];
    
    let arr2 = [
       {levelId: 'ABC_123', value: 10, label: 'tree', level: 'mid'},
       {levelId: 'ABC_456', value: 11, label: 'grass', level: 'top'},
       {levelId: 'ABC_789', value: 11, label: 'bush', level: 'low'}
    ];
    
    
    function mergeArr(a1, a2) {
        return a2.reduce((newArr, el) => {
          const has = a1.find((entry) => entry.id === el.levelId);
    
          if (!has) {
            newArr.push({
              id: el.levelId,
              value: el.value,
              label: el.label,
              level: el.level
            });
          }
    
          return newArr;
        }, a1)
    }
    
    console.log(mergeArr(arr1, arr2));