【问题标题】:How to sum value in the existing array object based on condition in javascript如何根据javascript中的条件对现有数组对象中的值求和
【发布时间】:2020-06-23 10:02:48
【问题描述】:

我有两个数组列表list1list2,属性name匹配,然后将list1和list2匹配对象的所有qty相加,返回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}
]

预期输出:

 [
  {id:1, name: "IN",qty: 3},
  {id:2, name: "TH", qty: 2},
  {id:3, name: "AU"}
]

【问题讨论】:

  • 不应该在输出对象中 TH 是 qty 2?... 列表 2 中名称缺失的项目会怎样?
  • @briosheje 感谢您的回复,我已经更新了输出,应该包含TH,在list2 中缺少名称也应该包含,
  • 如果在list2TH 的条目没有qty,会发生什么?没有qty 属性是什么意思?是否等同于qty: 0
  • @trincot 感谢 rply,是的,它相当于 qty: 0
  • 只是一个提示,考虑将您的问题包含在问题的正文中,而不仅仅是在标题中。它确实让您更清楚您在寻找什么。

标签: javascript arrays object javascript-objects


【解决方案1】:

您可以创建一个 Map 来创建结果列表,但按名称键入。 然后迭代第二个列表并相应地更新地图中的对象。 最后将值提取到结果列表中。

Map 的使用避免了您使用findfilter 或其他一些嵌套循环,并使算法在线性时间内运行。

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);

【讨论】:

    【解决方案2】:

    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)));

    这似乎解决了问题。第一个forEach 循环将所有数量相加。第二个循环构造结果,只查找list1 中的条目。请注意,这只有在 list1 中没有重复项时才能按预期工作。

    【讨论】:

      【解决方案3】:

      您也可以使用map函数,逻辑是从第二个列表中过滤项目并获取长度并添加一个作为当前元素,然后如果qty大于一个则相应地记录。这是工作示例:

      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);

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-10-28
        • 2022-01-02
        • 1970-01-01
        • 2021-10-21
        • 1970-01-01
        • 2020-04-06
        • 1970-01-01
        • 2018-06-22
        相关资源
        最近更新 更多