How to group by, calculate sum and get average in JavaScript array?

Tags: , , ,



I have array of object

 const users = [
     { group: 'editor', name: 'Adam', age: 23 },
     { group: 'admin', name: 'John', age: 28 },
     { group: 'editor', name: 'William', age: 34 },
     { group: 'admin', name: 'Oliver', age: 28' }
 ];

Expected result:

//sum
 sumAge = {
 editor: 57,  // 23+34
 admin: 56    // 28+28
}

//average
avgAge = {
   editor: 28.5,  // (23+34) / 2
   admin: 28    //(28+28)/2
}

I use reduce() method to group the objects in an array by ‘group’ and calulate sum:

let sumAge = users.reduce((group, age) => {
    group[age.group] = (group[age.group] || 0) + age.age || 1;
    return group;
}, {})
console.log('sumAge', sumAge); // sumAge: {editor: 57, admin: 56} 
done!

How to group object of Array by key ‘group’ and calulate average?. I tried:

let ageAvg= users.reduce((group, age) => {
      if (!group[age.group]) {
      group[age.group] = { ...age, count: 1 }
         return group;
      }
      group[age.group].age+= age.age;
      group[age.group].count += 1;
      return group;
      }, {})
const result = Object.keys(ageAvg).map(function(x){
     const item  = ageAvg[x];
     return {
         group: item.group,
         ageAvg: item.age/item.count,
     }
 })
console.log('result',result);
/*
result=[
    {group: "editor", ageAvg: 28.5}
    {group: "admin", ageAvg: 28}
]

But Expected result:

result = {
   editor: 28.5,  // (23+34) / 2
   admin: 28    //(28+28)/2
}

Answer

You could simply use reduce to get the total of age groups.

And use object.keys length to get the average of your total as new object from getAvg function.

Demo:

const users = [{
    group: 'editor',
    name: 'Adam',
    age: 23
  },
  {
    group: 'admin',
    name: 'John',
    age: 28
  },
  {
    group: 'editor',
    name: 'William',
    age: 34
  },
  {
    group: 'admin',
    name: 'Oliver',
    age: 28
  }
];

const sumId = users.reduce((a, {
  group,
  age
}) => (a[group] = (a[group] || 0) + age, a), {});

console.log(sumId); //{editor: 57, admin: 56}

//Average
const getAvg = (x) => {
  const item = {}
  const count = Object.keys(x).length
  Object.keys(x).map(function(y) {
    item[y] = sumId[y] / count
  })
  return item
}
console.log(getAvg(sumId)); //{editor: 28.5, admin: 28}


Source: stackoverflow