Reputation: 145
I have two array list list1
and list2
, property name
matches, then sum all the qty
of list1 and list2 matched object, return updated qty of list1
function resultantArray(list1, list2){
let sum = list2.map(o => o.qty|| 0).reduce((a, c) => { return a + c });
list1.forEach(item=>{
list2.find(elm => elm.productcode == item.productcode).qty= sum;
});
}
var list1 = [
{id:1, name: "IN",qty: 1},
{id:2, name: "TH"},
{id:3, name: "AU"}
]
var list2 = [
{id:3, name: "IN", qty:1},
{id:5, name: "IN", qty:1},
{id:4, name: "TH", qty: 2},
{id:1, name: "SG", qty: 3}
]
Expected Output:
[
{id:1, name: "IN",qty: 3},
{id:2, name: "TH", qty: 2},
{id:3, name: "AU"}
]
Upvotes: 1
Views: 1727
Reputation: 350776
You could create a Map to create the result list, but keyed by name. Then iterate the second list and update the objects in the map accordingly. Finally extract the values into the result list.
The use of the Map avoids that you have use find
or filter
or some other nested loop, and makes the algorithm run in linear time.
var list1 = [{id:1, name: "IN", qty: 1},{id:2, name: "TH"},{id:3, name: "AU"}]
var list2 = [{id:3, name: "IN", qty:1},{id:5, name: "IN", qty:1},{id:4, name: "TH", qty: 2},{id:1, name: "SG", qty: 3}];
const map = new Map(list1.map(o => [o.name, {...o}]));
for (let o of list2) {
let p = map.get(o.name);
if (p && o.qty) p.qty = (p.qty || 0) + o.qty;
}
const result = Array.from(map.values());
console.log(result);
Upvotes: 1
Reputation: 5308
You can also make use of map
function, logic would be to filter the item from second list and get length and add one for being the current element, afterwards if the qty
is more than one then record accordingly. Here is the working example:
var list1 = [
{id:1, name: "IN",qty: 1},
{id:2, name: "TH"},
{id:3, name: "AU"}
]
var list2 = [
{id:3, name: "IN", qty:1},
{id:5, name: "IN", qty:1},
{id:4, name: "TH", qty: 2},
{id:1, name: "SG", qty: 3}
]
var result = list1.map(item=>{
qty = list2.filter(k=>k.name==item.name).length+1;
return qty>1 ? {...item, qty} : item;
});
console.log(result);
Upvotes: 0
Reputation: 17955
var list1 = [
{id:1, name: "IN",qty: 1},
{id:2, name: "TH"},
{id:3, name: "AU"}
]
var list2 = [
{id:3, name: "IN", qty:1},
{id:5, name: "IN", qty:1},
{id:4, name: "TH", qty: 2},
{id:1, name: "SG", qty: 3}
]
function process(l1, l2) {
let qtys = {};
l1.concat(l2).forEach(o => {
let q = o.qty || 0;
if (qtys[o.name] === undefined) {
qtys[o.name] = o.qty; // track its qty
} else {
qtys[o.name] += o.qty; // add its qty
}
});
let id = 1;
return l1.map(o => {
let r = {id: id++, name: o.name};
if (qtys[o.name]) r.qty = qtys[o.name];
return r;
});
}
console.log(JSON.stringify(process(list1, list2)));
This seems to solve the problem. The first forEach
loop adds up all quantities. The second loop constructs the result, looking up only entries in list1
. Note that this only works as expected if there are no duplicates in list1
.
Upvotes: 0