How to group by riskTypeNo property and calulate sum and averge by selectedValue in javascript?

I have achieved the result by running separate reduce functions for sum and count and then creating finalobj using Object.entries. Can this be achieved with less and better code: { A1: { Avg: 4, Count: 1, Sum: 4 }, A13: { Avg: 3, Count: 1, Sum: 3 }, A4: { Avg: 1, Count: 1, Sum: 1 }, C6: { Avg: 1, Count: 1, Sum: 1 }, M1: { Avg: 1.75, Count: 4, Sum: 7 } }

My Code:

const riskTypeNoWithSelectedValue = [
  {
    "riskTypeNo": "A1",
    "selectedValue": 4
  },
  {
    "riskTypeNo": "M1",
    "selectedValue": 4
  },
  {
    "riskTypeNo": "C6",
    "selectedValue": 1
  },
  {
    "riskTypeNo": "M1",
    "selectedValue": 1
  },
  {
    "riskTypeNo": "M1",
    "selectedValue": 1
  },
  {
    "riskTypeNo": "A4",
    "selectedValue": 1
  },
  {
    "riskTypeNo": "M1",
    "selectedValue": 1
  },
  {
    "riskTypeNo": "A13",
    "selectedValue": 3
  }
];

const sumrRiskTypeNo = riskTypeNoWithSelectedValue.reduce((accumulator, {riskTypeNo,  selectedValue}) => (accumulator[riskTypeNo] = (accumulator[riskTypeNo] || 0) + selectedValue, accumulator), {});

        
        const countRiskTypeNo = riskTypeNoWithSelectedValue.reduce((accumulator, {riskTypeNo,  selectedValue}) => (accumulator[riskTypeNo] = (accumulator[riskTypeNo] || 0) + 1, accumulator), {});


const finalObj = {};
Object.entries(sumrRiskTypeNo).forEach(([k, v]) => {
    finalObj[k] = {"Sum": v, "Count": countRiskTypeNo[k], "Avg": v/countRiskTypeNo[k]}; 
});

console.log(finalObj);

Hi @asifakhtar, you might also calculate the result with a single reduce() to avoid iterating over the values multiple times, which would probably improve performance for very large datasets…

const finalObj = riskTypeNoWithSelectedValue.reduce((result, {
  riskTypeNo,
  selectedValue
}) => {
  const current = result[riskTypeNo] || {
    Count: 0,
    Sum: 0,
    Avg: 0
  }

  current.Count++
  current.Sum += selectedValue
  current.Avg = current.Sum / current.Count
  result[riskTypeNo] = current

  return result
}, {})

console.log(finalObj)
3 Likes

Thanks. It works. Appreciated.

1 Like