var players = [{id: 17, amount: 126},
{id: 17, amount: 45},
{id: 12, amount: 44},
{id: 12, amount: 23}];
How would i turn the above array into a new array adding the amount for each id.
var newArray=[{id:17.amount:171},{id:12,amount:67}];
var players = [{id: 17, amount: 126},
{id: 17, amount: 45},
{id: 12, amount: 44},
{id: 12, amount: 23}];
How would i turn the above array into a new array adding the amount for each id.
var newArray=[{id:17.amount:171},{id:12,amount:67}];
You could group the same id with a hash table and add the amount, where necessary.
var players = [{ id: 17, amount: 126 }, { id: 17, amount: 45 }, { id: 12, amount: 44 }, { id: 12, amount: 23 }],
grouped = players.reduce(function (hash) {
return function (r, a) {
(hash[a.id] = hash[a.id] || r[r.push({ id: a.id, amount: 0 }) - 1]).amount += a.amount;
return r;
};
}(Object.create(null)), []);
console.log(grouped);
Basically this line
(hash[a.id] = hash[a.id] || r[r.push({ id: a.id, amount: 0 }) - 1]).amount += a.amount;
checks if hash[a.id]
exists and if not, then this part
r[r.push({ id: a.id, amount: 0 }) - 1]
is perfomed, which contains of two parts, a part to access the result set and inside it pushes a new objetc set to the result set. While push
returns the new length of the array, it need to decrease the index to get the last inserted element.
r[ - 1]
r.push({ id: a.id, amount: 0 })
After that, take the property amount
and increase by the amount of the actual element.
Object.create(null)
instead of {}
?id
like 'toString' to break the hash table.{}
. You might also want to explain what's going on in here. Even with years of JS experience, this isn't exactly easy to read, not to mention understand.You could also change the output format a little, to make it easier to search:
var players = [{ id: 17, amount: 126 }, { id: 17, amount: 45 }, { id: 12, amount: 44 }, { id: 12, amount: 23 }],
result = {};
for(var i = 0; i < players.length; i++){
result[players[i].id] =
(result[players[i].id] || 0) + // The existing amount, or 0 for a new `id`
players[i].amount; // Add the current amount
}
console.log(result);
console.log('Amount for 17: ' + result[17]);
This way, you don't have to filter the result on it's id
value, to get the amount.
You could push element in a a new array if id is new or just add amount to the previous if it already exists :
var players = [{ id: 17, amount: 126 }, { id: 12, amount: 103 }, { id: 17, amount: 45 }, { id: 12, amount: 44 }, { id: 12, amount: 23 }];
var results = [];
results.push(players.sort((a,b) => a.id-b.id)[0]);
var shift = 0;
players.forEach((item, index, arr) => {
if (index < arr.length - 1){
if (item.id === arr[index+1].id) {
results[index + shift].amount += arr[index+1].amount;
shift--;
}
else results.push(players[index+1]);
}
});
console.log(results); // [ { id: 12, amount: 170 }, { id: 17, amount: 171 } ]
id
.