Reputation: 662
I want to return an array grouped by the team with gp, win, loss summed up. I'm trying to accomplish this with reduce, however, the totals are not adding up. Here's my code...
const myArr = [
{team: 'Red', gp: 3, win:2, loss:1},
{team: 'Black', gp: 3, win:1, loss:2},
{team: 'Red', gp: 10, win:8, loss:2}
]
let output = myArr.reduce(
(acc, curr) => {
acc[curr.team] = {
gp: acc.gp + curr.gp,
win: acc.win + curr.win,
loss: acc.loss + curr.loss
};
return acc;
}, {
gp: 0,
win: 0,
loss: 0
}
);
console.log(output);
This code returns the array in the format I need, however, the gp, win, loss is not summed up, instead it shows the last data point.
Upvotes: 1
Views: 1387
Reputation: 85
You could pass an empty array to the accumulator, then using the team property as key, you can check if those values are already defined on the accumulator array, if so then you sum the already defined values with the current ones, otherwise you just take the current values.
const myArr = [
{team: 'Red', gp: 3, win:2, loss:1},
{team: 'Black', gp: 3, win:1, loss:2},
{team: 'Red', gp: 10, win:8, loss:2}
]
let output = myArr.reduce(
(acc, curr) => {
acc[curr.team] = {
gp: acc[curr.team]?.gp ? acc[curr.team].gp + curr.gp : curr.gp,
win: acc[curr.team]?.win ? acc[curr.team].win + curr.win : curr.win,
loss: acc[curr.team]?.loss ? acc[curr.team].loss + curr.loss : curr.loss
};
return acc;
}, []
);
console.log(output);
Upvotes: 0
Reputation: 36311
I would reduce the items to a unique set using Set, then map each item to a new object.
const teams = [{team: 'Red', gp: 3, win:2, loss:1},
{team: 'Black', gp: 3, win:1, loss:2},
{team: 'Red', gp: 10, win:8, loss:2}]
let result = [...new Set(teams.map(t => t.team))].map(team => {
return {
team,
gp: teams.reduce((sum, val) => val.team == team ? sum + val.gp : sum, 0),
win: teams.reduce((sum, val) => val.team == team ? sum + val.win : sum, 0),
loss: teams.reduce((sum, val) => val.team == team ? sum + val.loss : sum, 0)
}
}, [])
console.log(result)
Upvotes: 0
Reputation: 386624
You need to take an empty object as accumulator and then you could take the wanted keys for adding.
const
myArr = [{ team: 'Red', gp: 3, win: 2, loss: 1 }, { team: 'Black', gp: 3, win: 1, loss: 2 }, { team: 'Red', gp: 10, win: 8, loss: 2 }],
keys = ['gp', 'win', 'loss'],
output = myArr.reduce((acc, curr) => {
acc[curr.team] = acc[curr.team] || Object.assign(...keys.map(k => ({ [k]: 0})));
keys.forEach(k => acc[curr.team][k] += curr[k]);
return acc;
}, Object.create(null));
console.log(output);
Upvotes: 3