Home > Enterprise >  Combine 2 array of objects if matches are found
Combine 2 array of objects if matches are found

Time:11-28

Hi,

I have these 2 arrays of objects:

const arr1 = [{"id":"pear","qty":2},{"id":"apple","qty":2}];
const arr2 = [{"id":"pear","qty":5},{"id":"lemon","qty":1}];

I want to combine them but at the same time summing their values in qty when they have the same id so this is the expected output:

[{"id":"pear","qty":7},{"id":"apple","qty":2},{"id":"lemon","qty":1}];

I tried this but it only keeps the first object:

const newArray = arr1.map((obj) => {
  const secondArrayObj = arr2.find((obj2) => obj2.id === obj.id);
  if (secondArrayObj) {
    return {...secondArrayObj, ...obj}
  }
  return null;
}).filter((obj) => obj != null);
console.log(newArray); 

What is the best approach here?

Thank you.

CodePudding user response:

For your code,the reason is that you are using Array.map(),it will only covnert arr1 to another array,and will not merge arr2

To solve it,we can do it via Array.reduce() and Array.filter()

const arr1 = [{"id":"pear","qty":2},{"id":"apple","qty":2}];
const arr2 = [{"id":"pear","qty":5},{"id":"lemon","qty":1}];

let arr3 = [...arr1,...arr2]
arr3 = arr3.reduce((a,v) => {
  let obj = a.find(i => i.id === v.id)
  if(obj){
   obj.qty  = v.qty 
   }else{
    a.push(v) 
   }
  return a
},[])
console.log(arr3)

CodePudding user response:

There are several ways to skin the cat. Here is one that uses an intermediate sums object, which performs well with large arrays:

const arr1 = [{"id":"pear","qty":2},{"id":"apple","qty":2}];
const arr2 = [{"id":"pear","qty":5},{"id":"lemon","qty":1}];

let sums = {};
arr1.concat(arr2).forEach(obj => {
  if(!sums[obj.id]) {
    sums[obj.id] = 0;
  }
  sums[obj.id]  = obj.qty;
});
let arr3 = Object.keys(sums).map(id => { return {id: id, qty: sums[id]}; });
console.log(arr3);

Output:

[
  {
    "id": "pear",
    "qty": 7
  },
  {
    "id": "apple",
    "qty": 2
  },
  {
    "id": "lemon",
    "qty": 1
  }
]

CodePudding user response:

  1. Combine both arrays
  2. Reduce them to an object keyed by id and value being the sum of qty
  3. Turn that object back into an array using Object.entries()
  4. Map that back to an array of objects

const arr1 = [{"id":"pear","qty":2},{"id":"apple","qty":2}];
const arr2 = [{"id":"pear","qty":5},{"id":"lemon","qty":1}];

const newArray = Object.entries(
  arr1.concat(arr2).reduce(
    (map, { id, qty }) => ({
      ...map,
      [id]: qty   (map[id] ?? 0),
    }),
    {}
  )
).map(([id, qty]) => ({ id, qty }));

console.log(newArray);
.as-console-wrapper { max-height: 100% !important; }

  • Related