javascript - 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"
}
]
我尝试混合使用reduce
andfindIndex
但它似乎不起作用,因为它只返回第一个值并且如果多个值不求和它们。
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 与我想要返回的字符串之间的问题。它根本无法将数学串在一起。虽然我想知道为什么它没有在附加的字符串中返回简单的数字......
无论如何,感谢大家的快速回答!
每个人都有很好的回答!
解决方案
您可以创建一个通用函数,它需要一个输入数组和一个数组键来合并。创建一个累加器对象,该对象将具有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']))
推荐阅读
- azure - az tag update 错误:(MissingSubscription)请求没有订阅或有效的租户级资源提供程序
- django - Django 创建电子邮件更改确认电子邮件
- java - 获取从 pom.xml 到 List 的依赖关系
- ros - 在 IMU 集成后,robot_localization 包中的线性速度,并且只有一个传感器 (IMU) 作为传感器输入
- javascript - 如何获得人类格式的持续时间(1小时4分钟)
- assembly - Pep8 数字分解
- laravel - 试图在 Laravel 8 中获取非对象的属性“名称”
- vue.js - V-model 正在更新未引用的状态数据
- docker - 在容器化应用程序中,Docker Engine 是否位于应用程序和操作系统之间?
- android - Android Out Of Memory Error Crash - 墓碑解读