Home > Software design >  How to merge arrays of objects by Id key?
How to merge arrays of objects by Id key?

Time:11-18

The function takes two array arguments and returns an array.

Arrays will contain objects representing some records.

The function must merge the two arrays into a new array under the following conditions:

  • Copy objects with unique Id property values (i.e. objects with an Id value present in one array only).
  • Merge objects with matching Id property values (i.e. objects with an Id value present in both arrays).
  • Every object in the array will have an Id property.
  • Original objects in both arrays must remain unchanged.

Merging objects means:

  1. Where both arrays contain a record with the same Id property value, the result should contain a record with properties of both records.
  2. Where both records have the same property name, use the value from the record in the second array.
const array1 = [
  { Id: 'a1' },
  { Id: 'a2', Name: 'Record 2', Cost: 4 } // Record a2 has Name and Cost properties
];

const array2 = [
  { Id: 'a2', Cost: 6 }, // Record a2 has a Cost property with a different value
  { Id: 'a3' }
];

const result = mergeArrays(array1, array2);

// Expected result
[
  { Id: 'a1' },
  { Id: 'a2', Name: 'Record 2', Cost: 6 }, // Name from array1 and Cost from array2
  { Id: 'a3' }
]

I have tried this:

function mergeArrays(array1, array2) {  

  let array3 = array1.map((item, i) => Object.assign({}, item, array2[i]));
  
  return array3

}

But the result is 2 objects instead of 3:

(2) [{…}, {…}]
0: {Id: 'a2', Cost: 6}
1: {Id: 'a3', Name: 'Record 2', Cost: 4}length: 2

Also this:

function mergeArrays(array1, array2) {  

  const result = array2.map(item => {
const searchedItem = array1.find(fItem => fItem['id'] === 
item['id'] );
if(searchedItem && Object.keys(searchedItem).length > 0 ){
  item['id'] = searchedItem['id']
}else{
   item['id'] = 'null'
}
 return item;
});
return result
}

But I keep receiving length = 2 when it should be 3.

I have tried everything that I found in here and can´t get it to return three objects as I should.

CodePudding user response:

Idea:

using reduce() would be a better option here. so the idea is first feed data of array2 into the reduce() as initial values. and then iterate through the array1 and look any Id of array1 already present in acc which holds values of array2. if acc has same Id that means we need to merge the entry with acc[idx] and update its old value. If it's not the case the two entries of array1 and array2 are unique so we need to push current item of array1 to acc as return [...acc, b].

const array1 = [{Id: 'a1'},{ Id: 'a2', Name: 'Record 2', Cost: 4 }]; 
const array2 = [{ Id: 'a2', Cost: 6 }, { Id: 'a3' }];

const mergeArrays = (arr1, arr2) => {
  return arr1.reduce((acc, b) => {
    const idx = acc.findIndex(item => item.Id === b.Id); //look for the acc has the same id while iterating array1
    if (idx > -1) { // if found need to merge with value of array2
      acc[idx] = Object.assign(b, acc[idx]);
      return acc;
    }
    return [...acc, b]; //if we don't find anything so "b" is an unique entry
  }, arr2); //inital values of reduce is from array2

}


console.log(mergeArrays(array1, array2));

  • Related