简体   繁体   中英

Add/Sum multiple values of array and display using Javascript/Python

var input = [{id: 1, price: 1200, profit:60, name:'Messi'},
             {id: 2, price: 600, profit:40, name:'Ronaldo'},
             {id: 1, price: 100, profit:40, name:'Messi'},
             {id: 1, price: 200, profit:30, name:'Messi'},
             {id: 2, price: 400, profit:10, name:'Ronaldo'},
             {id: 1, price: 800, profit:10, name:'Messi'}];

Expected Output:

[{id:1, name:'Messi', price:'2300', profit:'140'},
 {id:2, name:'Ronaldo', price:'1000', profit:'50'},
]

Tried:

var output = { };
input.forEach(e => output[e.id] = (output[e.id] || 0) + e.price);

console.log(output);

How to make like the expected output here.

You can use Array.prototype.reduce() combined with Nullish coalescing assignment (??=)

Code:

 const input = [{ id: 1, price: 1200, profit: 60, name: 'Messi' },{ id: 2, price: 600, profit: 40, name: 'Ronaldo' },{ id: 1, price: 100, profit: 40, name: 'Messi' },{ id: 1, price: 200, profit: 30, name: 'Messi' },{ id: 2, price: 400, profit: 10, name: 'Ronaldo' },{ id: 1, price: 800, profit: 10, name: 'Messi' },] const result = input.reduce((a, c) => { a[c.id]??= { id: c.id, name: c.name, price: 0, profit: 0 } a[c.id].price += c.price a[c.id].profit += c.profit return a }, {}) console.log(Object.values(result))

You can do it with the .reduce() method

 var input = [{ id: 1, price: 1200, profit: 60, name: 'Messi' }, { id: 2, price: 600, profit: 40, name: 'Ronaldo' }, { id: 1, price: 100, profit: 40, name: 'Messi' }, { id: 1, price: 200, profit: 30, name: 'Messi' }, { id: 2, price: 400, profit: 10, name: 'Ronaldo' }, { id: 1, price: 800, profit: 10, name: 'Messi' } ]; /* [{id:1, name:'Messi', price:'2300', profit:'140'}, {id:2, name:'Ronaldo', price:'1000', profit:'50'}] */ var result = []; //Initialize array //array reduce input.reduce(function(res, value) { if (.res[value.name]) { res[value:name] = { id. value,id: name. value,name: price, 0: profit; 0 }. result.push(res[value.name]) } res[value.name].price += value;price. //sums price key values res[value.name].profit += value;profit; //sums profit key values return res, //returns response }; {}). //output console.log(result)

There are two key things here.

  1. You need to loop over the array of objects.

    JavaScript provides several mechanisms for looping over arrays. You can use a traditional for statement . Or a for/of statement , or perhaps reduce as mentioned in the other answers.

  2. You need to be able to group information by the name provided in the objects.

    Objects are very useful here as they allow you to associate (read: "group") values with unique keys.

So, the general procedure is:

  1. Initialise an object to use for storing the keys (names) and values (some more objects)

  2. Loop over the input array. Take the name from the object and check to see if it exists as a key in the object. If it doesn't exist add it as a key, and then assign an initial object in the iteration as its value.

  3. Update the values of that object where appropriate

  4. Well, now you have an object of objects where what you want is an array of objects again, similar to your input. Use Object.values to return an array of the object's values (the nested objects).

Note: in your question your required output has the price and profit as strings rather than numbers so you may have to do an additional mapping operation on the array from Object.values to get that result. I've included that code at the end of the example along with some links to documentation of other code mentioned.)

In this example I'll use a for/of loop.

 const input=[{id:1,price:1200,profit:60,name:"Messi"},{id:2,price:600,profit:40,name:"Ronaldo"},{id:1,price:100,profit:40,name:"Messi"},{id:1,price:200,profit:30,name:"Messi"},{id:2,price:400,profit:10,name:"Ronaldo"},{id:1,price:800,profit:10,name:"Messi"}]; // Initialise an empty object const temp = {}; // For every object in the input array... for (const obj of input) { // Destructure the properties from it const { id, price, profit, name } = obj; // If the name doesn't exist as a key on the object // add it, and assign an initial object to it that mirrors // the current object in the iteration, but where the // values of the properties that you want to increase are // set to zero. The key is there just go to the next step temp[name]??= { id, name, price: 0, profit: 0 }; // Increase the price and profit values in // the initialised object temp[name].price += price; temp[name].profit += profit; } // Finally, after the iteration, we return // an array of those nested objects we've created const output = Object.values(temp); console.log(output); // If you want to strings for those values // you'll have to do an additional `map` to // stringify them const stringified = output.map(obj => { // Use destructuring to get the profit and // price properties, and assign everything else to `rest` const { price, profit, ...rest } = obj; // Return a new object by spreading out `rest`, // and coercing the numbers to strings return {...rest, price: price.toString(), profit: profit.toString() }; }); console.log(stringified);

Additional information

Instead of computing just price , you can also compute profit and also add id and name , the result of each id being an object instead of a number. Then use Object.values() to get the final result. As has been demonstrated elsewhere Array#reduce can also be used to give us the intermediate result.

 const input = [{id: 1, price: 1200, profit:60, name:'Messi'}, {id: 2, price: 600, profit:40, name:'Ronaldo'}, {id: 1, price: 100, profit:40, name:'Messi'}, {id: 1, price: 200, profit:30, name:'Messi'}, {id: 2, price: 400, profit:10, name:'Ronaldo'}, {id: 1, price: 800, profit:10, name:'Messi'}]; /*Expected Output: [{id:1, name:'Messi', price:'2300', profit:'140'}, {id:2, name:'Ronaldo', price:'1000', profit:'50'}, ] Tried:*/ const output = { }; input.forEach( e => output[e.id] = { id: e.id, name: e.name, price:(output[e.id]?.price || 0) + e.price, profit:(output[e.id]?.profit || 0) + e.profit }); console.log(Object.values(output));

Give this a shot:)

 var input = [{id: 1, price: 1200, profit:60, name:'Messi'}, {id: 2, price: 600, profit:40, name:'Ronaldo'}, {id: 1, price: 100, profit:40, name:'Messi'}, {id: 1, price: 200, profit:30, name:'Messi'}, {id: 2, price: 400, profit:10, name:'Ronaldo'}, {id: 1, price: 800, profit:10, name:'Messi'}]; function transform(input) { let output = [] let lookup = {} for (let i = 0; i < input.length; i++) { let item = input[i] let key = item.id if (lookup[key]) { lookup[key].price += item.price lookup[key].profit += item.profit } else { lookup[key] = {...item } } } for (let key in lookup) { output.push(lookup[key]) } return output } console.log(transform(input))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM