-1

I have an array of objects that I am looking to group by a given property and then aggregate through summing the properties. Here is an example of my data:

This is what I have:

const teams = [{posteam: 'ARI', week: 1, touchdowns: 2, fieldgoals: 3}, {posteam: 'ARI', week: 2, touchdowns: 4, fieldgoals: 1}, {posteam: 'ARI', week: 3, touchdowns: 1, fieldgoals: 4},{posteam: 'ATL', week: 1, touchdowns: 0, fieldgoals: 2}]

This is what I'm looking to make:

[{posteam: 'ARI', touchdowns: 7, fieldgoals: 8}, {posteam: 'ATL', touchdowns: 0, fieldgoals: 2}]

The "week" value isn't needed because it's only a label, not an actual measure. Otherwise, I'm looking to basically reduce the arrays' objects into one object per posteam. I've looked at the reduce and groupby functions, but neither seems to be the best solution for doing what Python's groupby and agg functions do. Ideally, I'd like to make this work in instances where there's only one object with a given posteam value.

jwald3
  • 19
  • 1
  • 6

2 Answers2

1

You can aggregate into an object with reduce then you take the values out of it. Use destructuring to keep week out of your aggregations:

const agg = teams =>
  Object.values(
    teams.reduce((o, {posteam, touchdowns, fieldgoals}) => {
      o[posteam] ??= {posteam, touchdowns: 0, fieldgoals: 0};
      o[posteam].touchdowns += touchdowns;
      o[posteam].fieldgoals += fieldgoals;
      return o;
    }, {}));
    
    

console.log(agg(teams));
<script>
const teams =
 [ {posteam: 'ARI', week: 1, touchdowns: 2, fieldgoals: 3}
 , {posteam: 'ARI', week: 2, touchdowns: 4, fieldgoals: 1}
 , {posteam: 'ARI', week: 3, touchdowns: 1, fieldgoals: 4}
 , {posteam: 'ATL', week: 1, touchdowns: 0, fieldgoals: 2}];
</script>
customcommander
  • 17,580
  • 5
  • 58
  • 84
0

I think you will have to iterate over and reduce stuff.

I have done it using Maps:

const teams = [{posteam: 'ARI', week: 1, touchdowns: 2, fieldgoals: 3}, {posteam: 'ARI', week: 2, touchdowns: 4, fieldgoals: 1}, {posteam: 'ARI', week: 3, touchdowns: 1, fieldgoals: 4},{posteam: 'ATL', week: 1, touchdowns: 0, fieldgoals: 2}]

teamsMap = new Map();

for(var obj in teams){
    if(teamsMap.get(teams[obj].posteam)){
        var currentObj = teamsMap.get(teams[obj].posteam);
        var newObj = {
            posteam:currentObj.posteam,
            touchdowns:currentObj.touchdowns+teams[obj].touchdowns,
            fieldgoals: currentObj.fieldgoals+teams[obj].fieldgoals
        }
        teamsMap.set(currentObj.posteam,newObj)
    } else {
        teamsMap.set(teams[obj].posteam,{...teams[obj]})
    }
}
var reducedTeams = Array.from(teamsMap.values())
console.log(reducedTeams)