首页 > 解决方案 > JS - 当多个键具有相同的值同时对其他值求和时合并对象

问题描述

这是我的数组:

[
  {
    "Date": "2019.07.08",
    "Organisation": "A",
    "Client": "Client1",
    "Product": "Pen",
    "Quantity": "1120"
  },
  {
    "Date": "2019.07.08",
    "Organisation": "A",
    "Client": "Client1",
    "Product": "Pen",
    "Quantity": "12003"
  },
  {
    "Date": "2019.07.08",
    "Organisation": "A",
    "Client": "Client1",
    "Product": "Ruler",
    "Quantity": "34706"
  },
  {
    "Date": "2019.07.07",
    "Organisation": "A",
    "Client": "Client1",
    "Product": "Ruler",
    "Quantity": "6158"
  },
  {
    "Date": "2019.07.07",
    "Organisation": "A",
    "Client": "Client1",
    "Product": "Pen",
    "Quantity": "3702"
  },
  {
    "Date": "2019.07.07",
    "Organisation": "A",
    "Client": "Client1",
    "Product": "Ruler",
    "Quantity": "158"
  },
  {
    "Date": "2019.07.07",
    "Organisation": "A",
    "Client": "Client2",
    "Product": "Pen",
    "Quantity": "80"
  },
  {
    "Date": "2019.07.07",
    "Organisation": "A",
    "Client": "Client2",
    "Product": "Ruler",
    "Quantity": "17200"
  },
  {
    "Date": "2019.07.08",
    "Organisation": "A",
    "Client": "Client3",
    "Product": "Pen",
    "Quantity": "393"
  },
  {
    "Date": "2019.07.08",
    "Organisation": "A",
    "Client": "Client3",
    "Product": "Pen",
    "Quantity": "4073"
  }
]

我想在 Date && Client && Product 相同时合并对象。
该解决方案可用于其他过滤器,例如在组织和客户端相同或仅产品等时合并相似的对象数组。

预期的输出是这样的:

[
  {
    "Date": "2019.07.08",
    "Organisation": "A",
    "Client": "Client1",
    "Product": "Pen",
    "Quantity": "13123"
  },
  {
    "Date": "2019.07.08",
    "Organisation": "A",
    "Client": "Client1",
    "Product": "Ruler",
    "Quantity": "34706"
  },
  {
    "Date": "2019.07.07",
    "Organisation": "A",
    "Client": "Client1",
    "Product": "Ruler",
    "Quantity": "6316"
  },
  {
    "Date": "2019.07.07",
    "Organisation": "A",
    "Client": "Client1",
    "Product": "Pen",
    "Quantity": "3702"
  },
  {
    "Date": "2019.07.07",
    "Organisation": "A",
    "Client": "Client2",
    "Product": "Pen",
    "Quantity": "80"
  },
  {
    "Date": "2019.07.07",
    "Organisation": "A",
    "Client": "Client2",
    "Product": "Ruler",
    "Quantity": "17200"
  },
  {
    "Date": "2019.07.08",
    "Organisation": "A",
    "Client": "Client3",
    "Product": "Pen",
    "Quantity": "4466"
  }
]

我尝试混合使用reduceandfindIndex但它似乎不起作用,因为它只返回第一个值并且如果多个值不求和它们。

var data = obj.reduce((acc, v) => {
    const index = acc.findIndex(o => {
        return o["Date"] === v["Date"] &&
            o["Product"] === v["Product"] &&
            o["Client"] === v["Client"]
    });

    if (index >= 0) {
        acc[index]["Quantity"] = 0;
        acc[index]["Quantity"] += Number(v["Quantity"]);
    }
    else {
        acc.push(v);
    }

    return acc;
}, []);

console.log(data);

return data;

编辑:
我的代码很好,我只需要更改 if 语句,我不知道为什么。

if (index >= 0) {
                var originalQty = Number(acc[index]["Quantity"]);
                originalQty += Number(v["Quantity"]);
                acc[index]["Quantity"] = originalQty.toString();
            }  

可能是我处理的 obj 与我想要返回的字符串之间的问题。它根本无法将数学串在一起。虽然我想知道为什么它没有在附加的字符串中返回简单的数字......

无论如何,感谢大家的快速回答!
每个人都有很好的回答!

标签: javascriptarraysjsonobject

解决方案


您可以创建一个通用函数,它需要一个输入数组和一个数组键来合并。创建一个累加器对象,该对象将具有keys数组中属性的每个唯一组合。

function merge(arr, keys) {
  const group = arr.reduce((acc, o) => {
    const unique = keys.map(k => o[k]).join('|');
    if(acc[unique])
      acc[unique].Quantity += +o.Quantity;
    else
      acc[unique] = { ...o, Quantity: +o.Quantity };
    return acc;
  }, {})

 return Object.values(group)
}

对于['Date', 'Client', 'Product']属性,这是group对象的外观。

{
  "2019.07.08|Client1|Pen": {
    "Date": "2019.07.08",
    "Organisation": "A",
    "Client": "Client1",
    "Product": "Pen",
    "Quantity": 13123
  },
  "2019.07.08|Client1|Ruler": {
    "Date": "2019.07.08",
    "Organisation": "A",
    "Client": "Client1",
    "Product": "Ruler",
    "Quantity": 34706
  },
  "2019.07.07|Client1|Ruler": {
    "Date": "2019.07.07",
    "Organisation": "A",
    "Client": "Client1",
    "Product": "Ruler",
    "Quantity": 6316
  },
  "2019.07.07|Client1|Pen": {
    "Date": "2019.07.07",
    "Organisation": "A",
    "Client": "Client1",
    "Product": "Pen",
    "Quantity": 3702
  },
  "2019.07.07|Client2|Pen": {
    "Date": "2019.07.07",
    "Organisation": "A",
    "Client": "Client2",
    "Product": "Pen",
    "Quantity": 80
  },
  "2019.07.07|Client2|Ruler": {
    "Date": "2019.07.07",
    "Organisation": "A",
    "Client": "Client2",
    "Product": "Ruler",
    "Quantity": 17200
  },
  "2019.07.08|Client3|Pen": {
    "Date": "2019.07.08",
    "Organisation": "A",
    "Client": "Client3",
    "Product": "Pen",
    "Quantity": 4466
  }
}

然后Object.values()用来获取这个对象的值作为一个数组

这是一个片段:

const arr = [{"Date":"2019.07.08","Organisation":"A","Client":"Client1","Product":"Pen","Quantity":"1120"},{"Date":"2019.07.08","Organisation":"A","Client":"Client1","Product":"Pen","Quantity":"12003"},{"Date":"2019.07.08","Organisation":"A","Client":"Client1","Product":"Ruler","Quantity":"34706"},{"Date":"2019.07.07","Organisation":"A","Client":"Client1","Product":"Ruler","Quantity":"6158"},{"Date":"2019.07.07","Organisation":"A","Client":"Client1","Product":"Pen","Quantity":"3702"},{"Date":"2019.07.07","Organisation":"A","Client":"Client1","Product":"Ruler","Quantity":"158"},{"Date":"2019.07.07","Organisation":"A","Client":"Client2","Product":"Pen","Quantity":"80"},{"Date":"2019.07.07","Organisation":"A","Client":"Client2","Product":"Ruler","Quantity":"17200"},{"Date":"2019.07.08","Organisation":"A","Client":"Client3","Product":"Pen","Quantity":"393"},{"Date":"2019.07.08","Organisation":"A","Client":"Client3","Product":"Pen","Quantity":"4073"}]

function merge(arr, keys) {
  const group = arr.reduce((acc, o) => {
    const unique = keys.map(k => o[k]).join('|');
    
    if(acc[unique])
      acc[unique].Quantity += +o.Quantity;
    else
      acc[unique] = { ...o, Quantity: +o.Quantity };
      
    return acc;
  }, {})
 
 return Object.values(group)
}

console.log(merge(arr, ['Date', 'Client', 'Product']))


推荐阅读