tengo los siguientes datos:
const data = [ {amount: 100, percent: 1, days: 7}, {amount: 75, percent: 3, days: 8}, {amount: 75, percent: 3, days: 3}, {amount: 100, percent: 2, days: 5}, {amount: 100, percent: 1, days: 10}, {amount: 50, percent: 3, days: 9} ];La tarea es agrupar objetos por cantidad y porcentaje, de modo que si la cantidad y el porcentaje en diferentes objetos son iguales, necesito sumar sus días. El resultado debería verse de la siguiente manera:
const data = [ {amount: 100, percent: 1, days: 17}, {amount: 75, percent: 3, days: 11}, {amount: 100, percent: 2, days: 5}, {amount: 50, percent: 3, days: 9} ];Los objetos 1 y 3 no se agrupan debido a un porcentaje diferente. He intentado usar el método de reducción:
const result = data.reduce((groupedByAmount, current) => { let amount = current.amount; let percent= current.percent; if (amount == amount && percent == percent) { groupedByAmount.amount = amount; current.days += current.days } return groupedByAmount }, { amount: 0, percent: null, days: 0 });No sé cómo verificar si la cantidad y el porcentaje son iguales, tal vez el mapa o el filtro ayudarían
const data = [ {amount: 100, percent: 1, days: 7}, {amount: 75, percent: 3, days: 8}, {amount: 75, percent: 3, days: 3}, {amount: 100, percent: 2, days: 5}, {amount: 100, percent: 1, days: 10}, {amount: 50, percent: 3, days: 9} ]; const doGroup = (data) => { const obj = data.reduce((result, next) => { const key = `${next.amount}_${next.percent}` const dd = result[key]?.days ?? 0; result[key] = {...next, days: next.days + dd}; return result; }, {}); return Object.values(obj); } console.log(doGroup(data))Teniendo en cuenta cada uno de los métodos que ha sugerido:
reduce => reduce los elementos de la matriz a un solo valor. Se puede usar para crear un objeto y luego volver a convertir ese objeto en la matriz
map => devuelve un valor para cada valor en la matriz
filter => devolver valores coincidentes múltiples (o únicos)
Puede recorrer cada valor, crear una nueva matriz y usar filter() para encontrar valores existentes para agregar.
Nota: es probable que esto no funcione bien con matrices grandes debido al uso múltiple de .filter() : usar una clave compuesta (combinar dos valores en un solo valor) probablemente funcione mejor.
const data = [ {amount: 100, percent: 1, days: 7}, {amount: 75, percent: 3, days: 8}, {amount: 75, percent: 3, days: 3}, {amount: 100, percent: 2, days: 5}, {amount: 100, percent: 1, days: 10}, {amount: 50, percent: 3, days: 9} ]; var result = []; data.forEach(e => { var current = result.filter(d => d.amount == e.amount && d.percent == e.percent); if (current.length === 0) { result.push(e); } else { current[0].days += e.days; } }); console.log(result); const data = [ {amount: 100, percent: 1, days: 7}, {amount: 75, percent: 3, days: 8}, {amount: 75, percent: 3, days: 3}, {amount: 100, percent: 2, days: 5}, {amount: 100, percent: 1, days: 10}, {amount: 50, percent: 3, days: 9} ]; const temp = data.reduce((acc, {amount, percent, days}) => { acc[amount] ||= {} acc[amount][percent] ||= 0 acc[amount][percent] += days return acc; } ,{}); const result = Object.entries(temp).reduce((acc, [amount, obj]) => { acc.push(...Object.entries(obj).map(([percent, days]) => ({ amount: Number(amount), percent: Number(percent), days }))) return acc },[]) console.log(result)