Tengo una serie de pedidos y necesito agruparlos según el código de transporte:
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", } ];hasta ahora hice esto:
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);que regresa
{ ups: 1, tnt: 3, dhl: 1 }y
[ { code: 'ups', orderscount: 1 }, { code: 'tnt', orderscount: 3 }, { code: 'dhl', orderscount: 1 } ]pero ahora necesito agrupar también por depósito e 'importar' algunos otros valores de los pedidos, como el recuento de cajas y el monto total de COD: prácticamente, y debería obtener algo como esto
[ { 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} ]¿Cómo puedo obtener esto con ES6/ES10?
Gracias
Aquí hay una manera de aprovechar solo esa primera función reduce() , junto con un operador de propagación para obtener lo que necesita.
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);No necesita hacer nada adicional, simplemente puede capturar todas las propiedades que desee en los objetos finales dentro de su reduce() .
Aquí aislando propiedades usando desestructuración y simplificando un poco la lógica con asignación lógica nula (??=)
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)); Para crear una matriz plana como en la respuesta aceptada, simplemente puede usar la misma lógica pero con una clave compuesta hecha de carrierCode depo
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));Puse el resultado en una estructura un poco diferente
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++; } });Resultado:
{ "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 } } }