Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

123
Vistas
Cómo combinar todos los objetos en uno basado en la clave

Aquí está el escenario que estoy viendo:

Quiero reducir estos objetos

 const data = [ { id: 1, totalAmount: 1500, date: '2021-01-01', vendor_id: 2, totalTransaction: 12, isRefund: false, }, { id: 2, totalAmount: 200, date: '2021-01-01', vendor_id: 2, totalTransaction: 2, isRefund: true, }, { id: 3, totalAmount: 200, date: '2021-01-01', vendor_id: 2, totalTransaction: 1, isRefund: true, }, ];

y encontré una solución que suma sus valores:

 const deepMergeSum = (obj1, obj2) => { return Object.keys(obj1).reduce((acc, key) => { if (typeof obj2[key] === 'object') { acc[key] = deepMergeSum(obj1[key], obj2[key]); } else if (obj2.hasOwnProperty(key) && !isNaN(parseFloat(obj2[key]))) { acc[key] = obj1[key] + obj2[key] } return acc; }, {}); }; const result = data.reduce((acc, obj) => (acc = deepMergeSum(acc, obj))); const array = [] const newArray = [...array, result]

lo que resulta en:

 const newArray = [ { id: 6, totalAmount: 1900, date: '2021-01-012021-01-012021-01-01', vendor_id: 6, totalTransaction: 15 } ]

Y ahora mi problema es que todavía no sé cómo resolver esto para obtener el resultado esperado, que si isRefund es verdadero, debe restarse en lugar de agregarse, conservar el vendor_id y también la date concatenada en lugar de una sola fecha de entrada :

 const newArray = [ { id: 1(generate new id if possible), totalAmount: 1100, date: '2021-01-01', vendor_id: 2, totalTransaction: 15, isRefund: null(this can be removed if not applicable), }, ];

Aceptaré y trataré de entender cualquier forma mejor o solución para esto. Muchísimas gracias.

about 4 years ago · Juan Pablo Isaza
2 Respuestas
Responde la pregunta

0

Como desea un comportamiento personalizado para varios campos y no necesita el aspecto recursivo de la combinación, le sugiero que cree una función de combinación personalizada, específica para su lógica comercial:

 const data = [{id: 1,totalAmount: 1500,date: '2021-01-01',vendor_id: 2,totalTransaction: 12,isRefund: false,},{id: 2,totalAmount: 200,date: '2021-01-01',vendor_id: 2,totalTransaction: 2,isRefund: true,},{id: 3,totalAmount: 200,date: '2021-01-01',vendor_id: 2,totalTransaction: 1,isRefund: true,},]; function customMerge(a, b) { if (a.vendor_id !== b.vendor_id || a.date !== b.date) { throw "Both date and vendor_id must be the same"; } return { id: Math.max(a.id, b.id), totalAmount: (a.isRefund ? -a.totalAmount : a.totalAmount) + (b.isRefund ? -b.totalAmount : b.totalAmount), date: a.date, vendor_id: a.vendor_id, totalTransaction: a.totalTransaction + b.totalTransaction }; } const result = data.reduce(customMerge); if (data.length > 1) result.id++; // Make id unique console.log(result);

También puede volver a introducir la propiedad isRefund en el resultado para cuando el monto total resulte ser negativo (solo haga esto cuando data.length > 1 ya que, de lo contrario, el result es solo el único objeto original en data ):

 result.isRefund = result.totalAmount < 0; result.totalAmount = Math.abs(result.totalAmount);

Resultados distintos para diferentes fechas y/o proveedores

A continuación, utilice un "diccionario" (objeto simple o Map ) con claves por combinaciones de fecha/proveedor, cada una con un objeto de agregación como valor.

Para demostrarlo, agregué un objeto más en los datos que tiene una fecha diferente y una cantidad de 300:

 const data = [{id: 1,totalAmount: 1500,date: '2021-01-01',vendor_id: 2,totalTransaction: 12,isRefund: false,},{id: 2,totalAmount: 200,date: '2021-01-01',vendor_id: 2,totalTransaction: 2,isRefund: true,},{id: 3,totalAmount: 200,date: '2021-01-01',vendor_id: 2,totalTransaction: 1,isRefund: true,},{id: 4,totalAmount: 300,date: '2021-01-02',vendor_id: 2,totalTransaction: 1,isRefund: false,}]; function customMerge(acc, {id, date, vendor_id, totalAmount, totalTransaction, isRefund}) { let key = date + "_" + vendor_id; if (!(id <= acc.id)) acc.id = id; acc[key] ??= { date, vendor_id, totalAmount: 0, totalTransaction: 0 }; acc[key].totalAmount += isRefund ? -totalAmount : totalAmount; acc[key].totalTransaction += totalTransaction; return acc; } let {id, ...grouped} = data.reduce(customMerge, {}); let result = Object.values(grouped).map(item => Object.assign(item, { id: ++id })); console.log(result);

about 4 years ago · Juan Pablo Isaza Denunciar

0

podría ser de ayuda, si está buscando el mismo resultado, puede agregar otra lista de verificación según sus requisitos, para la fecha filtrada, la lógica sería un poco diferente pero el resultado será el mismo.

 const getTotalTranscation = () => transctionLists.reduce((prev, current) => { const totalAmount = current.isRefund ? prev.totalAmount - current.totalAmount : prev.totalAmount + current.totalAmount; const totalTransaction = current.isRefund ? prev.totalTransaction - current.totalTransaction : prev.totalTransaction + current.totalTransaction; return { ...current, id: current.id + 1, totalAmount, totalTransaction, isRefund: totalAmount < 0, }; });
about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda