Tengo una matriz como
let array = [ { id: 1, name: "Name A", expenseAmount: 100 }, { id: 1, name: "Name A", expenseAmount: 50 }, { id: 3, name: "Name B", expenseAmount: 10 }, { id: 3, name: "Name B", expenseAmount: 20 } ];Y estoy buscando una solución, que condense esa matriz de tal manera que todos los objetos con la misma identificación y nombre se sumen por su cantidad de gastos, de modo que resulte en:
let array_goal = [ { id: 1, name: "Name A", expenseAmount: 150 }, { id: 3, name: "Name B", expenseAmount: 30 } ];¿Podrias ayudarme por favor? ¡Gracias!
Array.prototype.reduce es su amigo para tareas como estas.
Encuentre un objeto preexistente con la misma identificación y agréguelo al monto del gasto, si no puede encontrarlo, hágalo usted mismo y agréguelo a la matriz de salida.
let array = [{ id: 1, name: "Name A", expenseAmount: 100 }, { id: 1, name: "Name A", expenseAmount: 50 }, { id: 3, name: "Name B", expenseAmount: 10 }, { id: 3, name: "Name B", expenseAmount: 20 } ]; const condenseArray = (arr) => { return arr.reduce((out, {id, name, expenseAmount}) => { let data = out.find(({id: _id}) => _id === id); if (!data) { const newData = {id, name, expenseAmount: 0}; out = [...out, newData]; data = newData; } data.expenseAmount += expenseAmount; return out; }, []); }; console.log(condenseArray(array));Esta es una posible solución:
const mergeIdSumExpenses = (arr = array) => ( Object.values(arr.reduce( (fin, itm) => ({ ...fin, [itm.id]: { ...itm, expenseAmount: (fin[itm.id]?.expenseAmount || 0) + itm.expenseAmount } }), {} )) );Explicación
.reduce para iterar a través de la matriz y generar resultados como un objetoid del itm del elemento actual ya existe en el agregador fin ,itm.expenseAmount a la prop existente (clave: itm.id )itm.id )Object.values() para extraer solo los valores del objeto resultanteFragmento de código
let array = [{ id: 1, name: "Name A", expenseAmount: 100 }, { id: 1, name: "Name A", expenseAmount: 50 }, { id: 3, name: "Name B", expenseAmount: 10 }, { id: 3, name: "Name B", expenseAmount: 20 } ]; const mergeIdSumExpenses = (arr = array) => ( Object.values(arr.reduce( (fin, itm) => ({ ...fin, [itm.id]: { ...itm, expenseAmount: (fin[itm.id]?.expenseAmount || 0) + itm.expenseAmount } }), {} )) ); console.log(mergeIdSumExpenses());Primer paso
Usar filtro para agrupar por id y nombre
Segundo paso
Use map , filter , reduce para calcular la cantidad de gastos
const array = [ {id:1,name:"Name A",expenseAmount:100}, {id:1,name:"Name A",expenseAmount:50}, {id:1,name:"Name B",expenseAmount:100}, {id:3,name:"Name B",expenseAmount:10}, {id:3,name:"Name B",expenseAmount:20} ]; const unique = array .filter((element, index, arr) => index === arr.findIndex(e => e.id == element.id && e.name == element.name)) .map(u => { u.expenseAmount = array .filter(a => a.id == u.id && a.name == u.name) .reduce((n, {expenseAmount}) => n + expenseAmount, 0); return u; }); console.log(unique);