Home > Back-end >  How to merge two arrays of objects, filtering out matching ID's and merging objects with matchi
How to merge two arrays of objects, filtering out matching ID's and merging objects with matchi

Time:11-24

I need to combine two arrays of objects:

const local: [
    {id: 1, balance: 2200, ref: 'A'},
    {id: 2, balance: 2100, ref: 'C'}
]
const remote: [
    {id: 1, balance: 3300, ref: 'B'},
]

I need to merge these arrays, such any two objects with the same id are merged - keeping the same ID, keeping the balance from remote and combining their ref values, so the ideal output of this example would be:

  [
       { id: 1, balance: 3300, text: 'A / B' },
       { id: 2, balance: 2100, text: 'C' }
  ]

How would I do this? Ive tried the following:

function mergeFunc(remoteArray, localArray) {
    const newArray = [];
    //loop over one of the arrays
    for (const localObj of localArray) {
        //for each iteration, search for object with matching id in other array
        if(remoteArray.some(remoteObj => remoteObj.id === localObj.id)){
            //if found matching id, fetch this other object
            const id:matchingRemoteObj = remoteArray.find(item => item.id === localObj.id);
            //create new, merged, object
            const newObj = {id:matchingRemoteObj.id, balance: id:matchingRemoteObj.balance, text:`${localObj.text} / ${id:matchingRemoteObj.text}`}
            //push new value to array
            newArray.push(newObj);
        }
    }
    return newArray;
}

The issue is, this solution gives me an array of merged objects that had matching ID's. I need an array with all objects, only merging the ones with matching id's...

CodePudding user response:

The reason is below code,you just push match records,which cause this issue

if(remoteArray.some(remoteObj => remoteObj.id === localObj.id))

Below is a reference for you by using Array.map() and Array.find()

const local = [
    {id: 1, balance: 2200, ref: 'A'},
    {id: 2, balance: 2100, ref: 'C'}
]
const remote = [
    {id: 1, balance: 3300, ref: 'B'},
]

let result = local.map(e =>{
  let r = remote.find(i => i.id === e.id)
  let ref = r?.ref
  if(ref){
    e.balance = r.balance
    e.ref  = ' / '   ref
   }
  return e
})
console.log(result)


Update: If you want to make your original code works,you need to add else block if there is no match

const local = [
    {id: 1, balance: 2200, ref: 'A'},
    {id: 2, balance: 2100, ref: 'C'}
]
const remote = [
    {id: 1, balance: 3300, ref: 'B'},
]


function mergeFunc(remoteArray, localArray) {
    const newArray = [];
    //loop over one of the arrays
    for (const localObj of localArray) {
        //for each time, search for object with matching id in other array
        if(remoteArray.some(remoteObj => remoteObj.id === localObj.id)){
            //if found matching id, fetch this other object
            const matchingRemoteObj = remoteArray.find(item => item.id === localObj.id);
            //create new, merged, object
            const newObj = {id:matchingRemoteObj.id, balance: matchingRemoteObj.balance, text:`${localObj.ref} / ${matchingRemoteObj.ref}`}
            //push new value to array
            newArray.push(newObj);
        }else{
          // this will add not match record into result array
          newArray.push(localObj) 
        }
    }
    return newArray;
}

let result = mergeFunc(remote,local)
console.log(result)

CodePudding user response:

You can make use of array.map and array.find method,

To replace the balance of the match with the remote array you can use,

obj.balance = o.balance

To merge the ref string of matching id, you can use,

obj.ref = `${obj.ref} / ${o.ref}`

Working Snippet:

const local = [
    { id: 1, balance: 2200, ref: "A" },
    { id: 2, balance: 2100, ref: "C" },
  ];
  const remote = [{ id: 1, balance: 3300, ref: "B" }];

  const result = local.map((obj) => {
    remote.find((o) => {
      if (o.id === obj.id) {
        obj.balance = o.balance;
        obj.ref = `${obj.ref} / ${o.ref}`;
      }
    });
    return obj;
  });

  console.log(result);

  • Related