Hola y gracias por revisar mi pregunta.
Tengo una matriz de objetos que contiene múltiples entradas para la misma persona correspondientes a diferentes fechas. Necesito sumar los valores para cada persona.
const data = [ { name: "Bob", date: 3/27/22 value: 300 }, { name: "Alice", date: 1/13/22 value: 500 }, { name: "Bob", date: 5/13/22 value: 400 }, { name: "Alice", date: 4/19/22 value: 350 }, { name: "John", date: 2/15/22 value: 700 }, ]Necesito que el resultado sea:
const result = [ { name: "Bob", value: 700 }, { name: "Alice", value: 850 }, { name: "John", value: 700 }, ]¿Cómo puedo hacer esto de la manera más eficiente posible?
Hasta ahora, solo he podido lograr esto utilizando el método de matriz de filtro que devuelve el valor del nombre, empujando el resultado a una nueva matriz y sumando esa matriz. Sin embargo, no conozco todos los valores de nombre de antemano, por lo que esto no funcionará.
Gracias por tu tiempo
Una forma de hacerlo puede ser esta:
const data = [ { name: 'Bob', date: '3/27/22', value: 300, }, { name: 'Alice', date: '1/13/22', value: 500, }, { name: 'Bob', date: '5/13/22', value: 400, }, { name: 'Alice', date: '4/19/22', value: 350, }, { name: 'John', date: '2/15/22', value: 700, }, ]; let res = data.reduce((agg, curr) => { agg[curr.name] = (agg[curr.name] || 0) + curr.value; return agg; }, {}); const res2 = Object.keys(res).map((v) => { return { name: v, value: res[v], }; }); console.log(res2);Creo que este enfoque tiene un rendimiento razonable:
const data = [ { name: "Bob", value: 300 }, { name: "Alice", value: 500 }, { name: "Bob", value: 400 }, { name: "Alice", value: 350 }, { name: "John", value: 700 }, ]; const reduceData = (data) => data.reduce((acc, cur) => { const {name, value} = cur; // Get name and value from current item const item = acc.find(it => it.name === name); // Find in our accumulator the desired object item ? item.value += value : acc.push({name, value}); // Update object or create a new object if it doesn't exist return acc; // Return accumulator } , []); console.log(reduceData(data));Array.reduce toma una función interna como primer parámetro.
Esta función interna generalmente toma dos parámetros: uno será el "acumulador" que devolverá la función y el otro será el "elemento de matriz actual".
Array.reduce ejecutará la función interna en cada elemento de la matriz y finalmente devolverá su valor.
El parámetro "acumulador" que se pasa a la función interna en cada ejecución es el valor de retorno de la llamada de función interna anterior.
Array.reduce puede tener un parámetro adicional que es el valor del acumulador inicial pasado a la primera llamada de función interna (aquí usamos una matriz vacía).
Más información aquí -> https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce
Puedes hacer esto mapeando también
const data = [ { name: "Bob", date: ' 3 / 27 / 22', value: 1, }, { name: "Alice", date: '1 / 13 / 22', value: 2, }, { name: "Bob", date: '5 / 13 / 22', value: 1, }, { name: "Alice", date: ' 4 / 19 / 22', value: 2 }, { name: "John", date: '2 / 15 / 22', value: 3 }, ] const res = {}; for (let i = 0; i < data.length; i++) { if (res[data[i].name]) { //here if any key(name) is already present in res then we add the value in already present value of that name res[data[i].name].value += data[i].value } else { res[data[i].name] = data[i] //here we are inserting data into res object if doesn't find any key with already name present in it } } const res2 = Object.keys(res).map(person => { return { name: person, value: res[person].value } }) console.log(res2);