问题
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.
回答1:
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);
回答2:
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)
来源:https://stackoverflow.com/questions/53054224/using-reduce-to-group-by-and-sum