Reputation: 3079
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
. 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?
Upvotes: 0
Views: 76
Reputation: 164766
id
and value being the sum of qty
const arr1 = [{"id":"pear","qty":2},{"id":"apple","qty":2}];
const arr2 = [{"id":"pear","qty":5},{"id":"lemon","qty":1}];
const newArray = [
...arr1
.concat(arr2)
.reduce(
(map, { id, qty }) => map.set(id, qty + (map.get(id) ?? 0)),
new Map()
),
].map(([id, qty]) => ({ id, qty }));
console.log(newArray);
.as-console-wrapper { max-height: 100% !important; }
Upvotes: 0
Reputation: 7616
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
}
]
Upvotes: 1
Reputation: 13506
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)
Upvotes: 1