• Jobs
  • About Us
  • Jobs
    • Home
    • Jobs
    • Courses and challenges
  • Businesses
    • Home
    • Post vacancy
    • Our process
    • Pricing
    • Assessments
    • Payroll
    • Blog
    • Sales
    • Salary Calculator

0

93
Views
obtenga el precio total de una matriz de objetos por usuario específico usando .reduce en javascript

Tengo esta matriz de objetos.

 const items = [ { id: '121', itemDate: '2022-04-28', itemName: 'testname1', itemCategory: 'Category A', itemPrice: { price: '100', currency: 'GBP' }, createdBy: { username: 'user1', name: 'Name 1', date: '2022-04-28T22:41:59', }, }, { id: '122', itemDate: '2022-04-28', itemName: 'testname2', itemCategory: 'Category B', itemPrice: { price: '100', currency: 'GBP' }, createdBy: { username: 'user2', name: 'Name 2', date: '2022-04-28T22:42:44', }, }, { id: '122', itemDate: '2022-04-28', itemName: 'testname3', itemCategory: 'Category C', itemPrice: { price: '200', currency: 'GBP' }, createdBy: { username: 'user2', name: 'Name 2', date: '2022-04-28T22:43:16', }, }, ]

Código que estoy usando:

 items.reduce(function (c, x) { if (!c[x.createdBy.username]) c[x.createdBy.username] = { username: x.createdBy.username, total: 0, } c[x.createdBy.username].total += Number(x.itemPrice.price) return c }, [])

Esta parte me da el siguiente resultado:

 items :>> [ user1: { username: 'user1', total: 100}, user2: { username: 'user2', total: 300} ]

Así que probé esto para deshacerme de los nombres de los objetos:

 let output = [] let totalSum = 0 for (const username in items) { let temp = { username: items[username].username, total: items[username].total, } totalSum = totalSum + items[username].total output.push(temp) } output.push({ username: 'allUsers', total: totalSum }) return output

Y el resultado final es como lo quiero ahora:

 output :>> [ { username: 'user1', total: 100 }, { username: 'user2', total: 300 }, { username: 'allUsers', total: 400} ]

Mis dos preguntas...

¿Hay alguna manera de actualizar la parte .reduce para obtener un objeto sin el nombre al principio, sin tener que usar el ciclo for?

¿Hay también una forma de implementar la parte que sumaría todos los totales?

Gracias

over 3 years ago · Juan Pablo Isaza
2 answers
Answer question

0

Ejemplo de código (sin comentarios/descripción)

 const groupAndAdd = arr => ( Object.values( arr.reduce( (acc, {createdBy : {username}, itemPrice: {price}}) => { acc.allUsers ??= { username: 'allUsers', total: 0}; acc.allUsers.total += +price; if (username in acc) { acc[username].total += +price; } else { acc[username] = {username, total: +price}; } return acc; }, {} ) ) );

A continuación se presenta una demostración de trabajo para lograr el objetivo deseado, con notas/comentarios para ayudar a comprender.

Fragmento de código

 // method to group by user and sum prices const groupAndAdd = arr => ( // extract the values from the intermediate result-object Object.values( arr.reduce( // generate result as object (acc, {createdBy : {username}, itemPrice: {price}}) => { // above line uses de-structuring to directly access username, price // below uses logical nullish assignment to set-up "allUsers" acc.allUsers ??= { username: 'allUsers', total: 0}; // accumulate the "price" to the all-users "total" acc.allUsers.total += +price; // if "acc" (accumulator) has "username", simply add price to total if (username in acc) { acc[username].total += +price; } else { // create an object for the "username" with initial total as "price" acc[username] = {username, total: +price}; } // always return the "acc" accumulator for ".reduce()" return acc; }, {} // initially set the "acc" to empty object ) ) // if required, use ".sort()" to move the all-users to last position in array ); const items = [{ id: '121', itemDate: '2022-04-28', itemName: 'testname1', itemCategory: 'Category A', itemPrice: { price: '100', currency: 'GBP' }, createdBy: { username: 'user1', name: 'Name 1', date: '2022-04-28T22:41:59', }, }, { id: '122', itemDate: '2022-04-28', itemName: 'testname2', itemCategory: 'Category B', itemPrice: { price: '100', currency: 'GBP' }, createdBy: { username: 'user2', name: 'Name 2', date: '2022-04-28T22:42:44', }, }, { id: '122', itemDate: '2022-04-28', itemName: 'testname3', itemCategory: 'Category C', itemPrice: { price: '200', currency: 'GBP' }, createdBy: { username: 'user2', name: 'Name 2', date: '2022-04-28T22:43:16', }, }, ]; console.log('group and add prices per user: ', groupAndAdd(items));
 .as-console-wrapper { max-height: 100% !important; top: 0 }

Explicación

Se agregaron comentarios en línea al fragmento anterior.

PD: si desea agregar valor a la comunidad stackoverflow,

Por favor considere leer: Qué hacer cuando mi pregunta es respondida ¡Gracias!

over 3 years ago · Juan Pablo Isaza Report

0

Para su primera pregunta, está inicializando correctamente como una matriz, pero está usando solo un objeto. Dos formas en que puedes hacer esto.

Primera opción

 let something = items.reduce(function(c, x) { if (!c[x.createdBy.username]) c[x.createdBy.username] = { username: x.createdBy.username, total: 0, } c[x.createdBy.username].total += Number(x.itemPrice.price) return c }, {}); something = Object.values(something);

Segunda opción

Estaba pensando en usar solo empujar, pero parece que no es posible, por lo que la anterior es la única opción.

Es posible usar push, pero se volverá demasiado complicado al verificar con find y actualizar el elemento de matriz correcto.


Para su segunda pregunta de sumar todos los totales, puede usar la sintaxis simple de:

 const sum = arr.reduce((a, c) => a + c, 0);

Este es el código mínimo que necesita para sumar una matriz de números.

over 3 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Our process Sales
Legal
Terms and conditions Privacy policy
© 2025 PeakU Inc. All Rights Reserved.

Andres GPT

Show me some job opportunities
There's an error!