codecat
codecat

Reputation: 145

How to sum value in the existing array object based on condition in javascript

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

Answers (3)

trincot
trincot

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

Rajneesh
Rajneesh

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

tucuxi
tucuxi

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

Related Questions