ES6 / ES9 通过多个参数对对象数组进行分组
ES6 / ES9 group array of objects by multiple parameters
我有一个订单数组,我需要根据 carrierCode 对它们进行分组:
const orders = [
{
"depo": "Berlin",
"boxes": 1,
"isCOD": true,
"CODAmount": 45.33,
"carrierCode": "ups",
"sid": "DCAC298A627DF2D1980D23F67F05E8E4",
},
{
"depo": "Leipzig",
"boxes": 2,
"isCOD": false,
"CODAmount": 0,
"carrierCode": "tnt",
"sid": "8BF93B9159742250CA7F73304808E316",
},
{
"depo": "Leipzig",
"boxes": 2,
"isCOD": true,
"CODAmount": 124.00,
"carrierCode": "dhl",
"sid": "0DC1A9BCFA6C5834361AFABBD857CEDD",
},
{
"depo": "Leipzig",
"boxes": 3,
"isCOD": true,
"CODAmount": 415.33,
"carrierCode": "tnt",
"sid": "8BF93B9159742250CA7F73304808E316",
},
{
"depo": "Berlin",
"boxes": 1,
"isCOD": false,
"CODAmount": 0,
"carrierCode": "tnt",
"sid": "0DC1A9BCFA6C5834361AFABBD857CEDD",
}
];
到目前为止我这样做了:
var groups = orders.reduce((p, c) => {
var code = c.carrierCode;
if (!p.hasOwnProperty(code)) {
p[code] = 0;
}
p[code]++;
return p;
}, {});
console.log(groups);
var countsExtended = Object.keys(groups).map(k => {
return {code: k, orderscount: groups[k]}; });
console.log(countsExtended);
那个returns
{ ups: 1, tnt: 3, dhl: 1 }
和
[
{ code: 'ups', orderscount: 1 },
{ code: 'tnt', orderscount: 3 },
{ code: 'dhl', orderscount: 1 }
]
但现在我还需要按 depo 和 'import' 订单中的一些其他值进行分组,例如箱数和 COD 总金额:实际上,我应该得到这样的结果
[
{ code: 'ups', orderscount: 1, depo:'Berlin', boxes: 1, CODAmount: 45.33},
{ code: 'tnt', orderscount: 1, depo:'Berlin', boxes: 1, CODAmount: 0.00},
{ code: 'tnt', orderscount: 2, depo:'Leipzig', boxes: 5, CODAmount: 415.33},
{ code: 'dhl', orderscount: 1, depo:'Leipzig', boxes: 2, CODAmount: 124.00}
]
如何使用 ES6/ES10 获得此信息?
谢谢
这里有一种方法可以利用第一个 reduce()
函数,以及一个扩展运算符来获得您需要的东西。
const orders = [{ depo: 'Berlin', boxes: 1, isCOD: true, CODAmount: 45.33, carrierCode: 'ups', sid: 'DCAC298A627DF2D1980D23F67F05E8E4', }, { depo: 'Leipzig', boxes: 2, isCOD: false, CODAmount: 0, carrierCode: 'tnt', sid: '8BF93B9159742250CA7F73304808E316', }, { depo: 'Leipzig', boxes: 2, isCOD: true, CODAmount: 124.0, carrierCode: 'dhl', sid: '0DC1A9BCFA6C5834361AFABBD857CEDD', }, { depo: 'Leipzig', boxes: 3, isCOD: true, CODAmount: 415.33, carrierCode: 'tnt', sid: '8BF93B9159742250CA7F73304808E316', }, { depo: 'Berlin', boxes: 1, isCOD: false, CODAmount: 0, carrierCode: 'tnt', sid: '0DC1A9BCFA6C5834361AFABBD857CEDD', },];
const groups = orders.reduce((p, c) => {
delete c.sid;
delete c.isCOD;
let index = p.findIndex(pi => pi.carrierCode == c.carrierCode && pi.depo == c.depo);
if (index > -1) {
p[index].ordercounts++;
p[index].CODAmount+=+c.CODAmount;
p[index].boxes+=+c.boxes;
}
else p.push({ ...c, ordercounts: 1});
return p;
}, []);
console.log(groups);
您不需要做任何额外的事情,您只需在 reduce()
.
的最终对象中捕获您想要的所有属性
此处使用 destructuring and simplifying the logic a little with logical nullish assignment (??=)
隔离属性
const orders = [{ depo: 'Berlin', boxes: 1, isCOD: true, CODAmount: 45.33, carrierCode: 'ups', sid: 'DCAC298A627DF2D1980D23F67F05E8E4', }, { depo: 'Leipzig', boxes: 2, isCOD: false, CODAmount: 0, carrierCode: 'tnt', sid: '8BF93B9159742250CA7F73304808E316', }, { depo: 'Leipzig', boxes: 2, isCOD: true, CODAmount: 124.0, carrierCode: 'dhl', sid: '0DC1A9BCFA6C5834361AFABBD857CEDD', }, { depo: 'Leipzig', boxes: 3, isCOD: true, CODAmount: 415.33, carrierCode: 'tnt', sid: '8BF93B9159742250CA7F73304808E316', }, { depo: 'Berlin', boxes: 1, isCOD: false, CODAmount: 0, carrierCode: 'tnt', sid: '0DC1A9BCFA6C5834361AFABBD857CEDD', },];
const groups = Object.values(
orders.reduce((p, { carrierCode: code, depo, boxes, CODAmount }) => {
p[code] ??= { code, orderscount: 0, depo: {} };
p[code]['depo'][depo] ??= { depo, boxes: 0, CODAmount: 0 };
p[code]['depo'][depo].boxes += boxes;
p[code]['depo'][depo].CODAmount += CODAmount;
p[code].orderscount += 1;
return p;
}, {})
).map(({ depo, ...rest }) => ({ ...rest, depo: Object.values(depo) }));
console.log(Object.values(groups));
要按照已接受的答案创建平面数组,您可以简单地使用相同的逻辑,但使用由 depo
和 carrierCode
.
组成的复合键
const orders = [{ depo: 'Berlin', boxes: 1, isCOD: true, CODAmount: 45.33, carrierCode: 'ups', sid: 'DCAC298A627DF2D1980D23F67F05E8E4', }, { depo: 'Leipzig', boxes: 2, isCOD: false, CODAmount: 0, carrierCode: 'tnt', sid: '8BF93B9159742250CA7F73304808E316', }, { depo: 'Leipzig', boxes: 2, isCOD: true, CODAmount: 124.0, carrierCode: 'dhl', sid: '0DC1A9BCFA6C5834361AFABBD857CEDD', }, { depo: 'Leipzig', boxes: 3, isCOD: true, CODAmount: 415.33, carrierCode: 'tnt', sid: '8BF93B9159742250CA7F73304808E316', }, { depo: 'Berlin', boxes: 1, isCOD: false, CODAmount: 0, carrierCode: 'tnt', sid: '0DC1A9BCFA6C5834361AFABBD857CEDD', },];
const groups = Object.values(
orders.reduce((p, { carrierCode: code, depo, boxes, CODAmount }) => {
const key = `${code}_${depo}`;
p[key] ??= { code, depo, orderscount: 0, boxes: 0, CODAmount: 0 };
p[key].orderscount += 1;
p[key].boxes += boxes;
p[key].CODAmount += CODAmount;
return p;
}, {})
);
console.log(Object.values(groups));
我把结果放在有点不同的结构中
const result = {};
orders.forEach(({ carrierCode, depo, boxes, CODAmount }) => {
if (!result[carrierCode]) {
result[carrierCode] = {};
}
if (!result[carrierCode][depo]) {
result[carrierCode][depo] = { boxes, CODAmount, orderscount: 1 };
} else {
result[carrierCode][depo].boxes += boxes;
result[carrierCode][depo].CODAmount += CODAmount;
result[carrierCode][depo].orderscount++;
}
});
结果:
{
"ups": {
"Berlin": {
"boxes": 1,
"CODAmount": 45.33,
"orderscount": 1
}
},
"tnt": {
"Leipzig": {
"boxes": 5,
"CODAmount": 415.33,
"orderscount": 2
},
"Berlin": {
"boxes": 1,
"CODAmount": 0,
"orderscount": 1
}
},
"dhl": {
"Leipzig": {
"boxes": 2,
"CODAmount": 124,
"orderscount": 1
}
}
}
我有一个订单数组,我需要根据 carrierCode 对它们进行分组:
const orders = [
{
"depo": "Berlin",
"boxes": 1,
"isCOD": true,
"CODAmount": 45.33,
"carrierCode": "ups",
"sid": "DCAC298A627DF2D1980D23F67F05E8E4",
},
{
"depo": "Leipzig",
"boxes": 2,
"isCOD": false,
"CODAmount": 0,
"carrierCode": "tnt",
"sid": "8BF93B9159742250CA7F73304808E316",
},
{
"depo": "Leipzig",
"boxes": 2,
"isCOD": true,
"CODAmount": 124.00,
"carrierCode": "dhl",
"sid": "0DC1A9BCFA6C5834361AFABBD857CEDD",
},
{
"depo": "Leipzig",
"boxes": 3,
"isCOD": true,
"CODAmount": 415.33,
"carrierCode": "tnt",
"sid": "8BF93B9159742250CA7F73304808E316",
},
{
"depo": "Berlin",
"boxes": 1,
"isCOD": false,
"CODAmount": 0,
"carrierCode": "tnt",
"sid": "0DC1A9BCFA6C5834361AFABBD857CEDD",
}
];
到目前为止我这样做了:
var groups = orders.reduce((p, c) => {
var code = c.carrierCode;
if (!p.hasOwnProperty(code)) {
p[code] = 0;
}
p[code]++;
return p;
}, {});
console.log(groups);
var countsExtended = Object.keys(groups).map(k => {
return {code: k, orderscount: groups[k]}; });
console.log(countsExtended);
那个returns
{ ups: 1, tnt: 3, dhl: 1 }
和
[
{ code: 'ups', orderscount: 1 },
{ code: 'tnt', orderscount: 3 },
{ code: 'dhl', orderscount: 1 }
]
但现在我还需要按 depo 和 'import' 订单中的一些其他值进行分组,例如箱数和 COD 总金额:实际上,我应该得到这样的结果
[
{ code: 'ups', orderscount: 1, depo:'Berlin', boxes: 1, CODAmount: 45.33},
{ code: 'tnt', orderscount: 1, depo:'Berlin', boxes: 1, CODAmount: 0.00},
{ code: 'tnt', orderscount: 2, depo:'Leipzig', boxes: 5, CODAmount: 415.33},
{ code: 'dhl', orderscount: 1, depo:'Leipzig', boxes: 2, CODAmount: 124.00}
]
如何使用 ES6/ES10 获得此信息?
谢谢
这里有一种方法可以利用第一个 reduce()
函数,以及一个扩展运算符来获得您需要的东西。
const orders = [{ depo: 'Berlin', boxes: 1, isCOD: true, CODAmount: 45.33, carrierCode: 'ups', sid: 'DCAC298A627DF2D1980D23F67F05E8E4', }, { depo: 'Leipzig', boxes: 2, isCOD: false, CODAmount: 0, carrierCode: 'tnt', sid: '8BF93B9159742250CA7F73304808E316', }, { depo: 'Leipzig', boxes: 2, isCOD: true, CODAmount: 124.0, carrierCode: 'dhl', sid: '0DC1A9BCFA6C5834361AFABBD857CEDD', }, { depo: 'Leipzig', boxes: 3, isCOD: true, CODAmount: 415.33, carrierCode: 'tnt', sid: '8BF93B9159742250CA7F73304808E316', }, { depo: 'Berlin', boxes: 1, isCOD: false, CODAmount: 0, carrierCode: 'tnt', sid: '0DC1A9BCFA6C5834361AFABBD857CEDD', },];
const groups = orders.reduce((p, c) => {
delete c.sid;
delete c.isCOD;
let index = p.findIndex(pi => pi.carrierCode == c.carrierCode && pi.depo == c.depo);
if (index > -1) {
p[index].ordercounts++;
p[index].CODAmount+=+c.CODAmount;
p[index].boxes+=+c.boxes;
}
else p.push({ ...c, ordercounts: 1});
return p;
}, []);
console.log(groups);
您不需要做任何额外的事情,您只需在 reduce()
.
此处使用 destructuring and simplifying the logic a little with logical nullish assignment (??=)
隔离属性const orders = [{ depo: 'Berlin', boxes: 1, isCOD: true, CODAmount: 45.33, carrierCode: 'ups', sid: 'DCAC298A627DF2D1980D23F67F05E8E4', }, { depo: 'Leipzig', boxes: 2, isCOD: false, CODAmount: 0, carrierCode: 'tnt', sid: '8BF93B9159742250CA7F73304808E316', }, { depo: 'Leipzig', boxes: 2, isCOD: true, CODAmount: 124.0, carrierCode: 'dhl', sid: '0DC1A9BCFA6C5834361AFABBD857CEDD', }, { depo: 'Leipzig', boxes: 3, isCOD: true, CODAmount: 415.33, carrierCode: 'tnt', sid: '8BF93B9159742250CA7F73304808E316', }, { depo: 'Berlin', boxes: 1, isCOD: false, CODAmount: 0, carrierCode: 'tnt', sid: '0DC1A9BCFA6C5834361AFABBD857CEDD', },];
const groups = Object.values(
orders.reduce((p, { carrierCode: code, depo, boxes, CODAmount }) => {
p[code] ??= { code, orderscount: 0, depo: {} };
p[code]['depo'][depo] ??= { depo, boxes: 0, CODAmount: 0 };
p[code]['depo'][depo].boxes += boxes;
p[code]['depo'][depo].CODAmount += CODAmount;
p[code].orderscount += 1;
return p;
}, {})
).map(({ depo, ...rest }) => ({ ...rest, depo: Object.values(depo) }));
console.log(Object.values(groups));
要按照已接受的答案创建平面数组,您可以简单地使用相同的逻辑,但使用由 depo
和 carrierCode
.
const orders = [{ depo: 'Berlin', boxes: 1, isCOD: true, CODAmount: 45.33, carrierCode: 'ups', sid: 'DCAC298A627DF2D1980D23F67F05E8E4', }, { depo: 'Leipzig', boxes: 2, isCOD: false, CODAmount: 0, carrierCode: 'tnt', sid: '8BF93B9159742250CA7F73304808E316', }, { depo: 'Leipzig', boxes: 2, isCOD: true, CODAmount: 124.0, carrierCode: 'dhl', sid: '0DC1A9BCFA6C5834361AFABBD857CEDD', }, { depo: 'Leipzig', boxes: 3, isCOD: true, CODAmount: 415.33, carrierCode: 'tnt', sid: '8BF93B9159742250CA7F73304808E316', }, { depo: 'Berlin', boxes: 1, isCOD: false, CODAmount: 0, carrierCode: 'tnt', sid: '0DC1A9BCFA6C5834361AFABBD857CEDD', },];
const groups = Object.values(
orders.reduce((p, { carrierCode: code, depo, boxes, CODAmount }) => {
const key = `${code}_${depo}`;
p[key] ??= { code, depo, orderscount: 0, boxes: 0, CODAmount: 0 };
p[key].orderscount += 1;
p[key].boxes += boxes;
p[key].CODAmount += CODAmount;
return p;
}, {})
);
console.log(Object.values(groups));
我把结果放在有点不同的结构中
const result = {};
orders.forEach(({ carrierCode, depo, boxes, CODAmount }) => {
if (!result[carrierCode]) {
result[carrierCode] = {};
}
if (!result[carrierCode][depo]) {
result[carrierCode][depo] = { boxes, CODAmount, orderscount: 1 };
} else {
result[carrierCode][depo].boxes += boxes;
result[carrierCode][depo].CODAmount += CODAmount;
result[carrierCode][depo].orderscount++;
}
});
结果:
{
"ups": {
"Berlin": {
"boxes": 1,
"CODAmount": 45.33,
"orderscount": 1
}
},
"tnt": {
"Leipzig": {
"boxes": 5,
"CODAmount": 415.33,
"orderscount": 2
},
"Berlin": {
"boxes": 1,
"CODAmount": 0,
"orderscount": 1
}
},
"dhl": {
"Leipzig": {
"boxes": 2,
"CODAmount": 124,
"orderscount": 1
}
}
}