I have an array of Orders and I need to group them according to the 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",
}
];
so far I did this:
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);
that returns
{ ups: 1, tnt: 3, dhl: 1 }
and
[
{ code: 'ups', orderscount: 1 },
{ code: 'tnt', orderscount: 3 },
{ code: 'dhl', orderscount: 1 }
]
but now I need to group also by depo and 'import' some other values from orders like boxes count, and total COD Amount: practically, and I should get something like this
[
{ 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}
]
how can I get this with ES6/ES10?
Thanks
CodePudding user response:
Here's a way to leverage just that first reduce()
function, along with a spread operator to get what you need.
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);
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
CodePudding user response:
You don't need to do anything extra, you can simply capture all the properties that you want in the final objects within your reduce()
.
Here isolating properties using 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));
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
CodePudding user response:
I put the result in a bit different structure
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 ;
}
});
Result:
{
"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
}
}
}