Skip to content
Advertisement

javascript Sum all item in array which match same key [closed]

I have a JSON like this:

  [
   {
      "faculty":{
         "_id":"5f9c3e04e5a5423cec34b2e2",
         "code":"khmt",
         "facultyName":"Computer Science"
      },
      "classSize":91,
      "warnedLength":61
   },
   {
      "faculty":{
         "_id":"5f9c53c8a0db8f4240ec6f71",
         "code":"dtvt",
         "facultyName":"Electronics and Telecommunication"
      },
      "classSize":89,
      "warnedLength":44
   },
   {
      "faculty":{
         "_id":"5f9c53c8a0db8f4240ec6f71",
         "code":"dtvt",
         "facultyName":"Electronics and Telecommunication"
      },
      "classSize":59,
      "warnedLength":20
   },
   {
      "faculty":{
         "_id":"5f9c53c8a0db8f4240ec6f71",
         "code":"hkvt",
         "facultyName":"Space Airline"
      },
      "classSize":10,
      "warnedLength":5
   },
   {
      "faculty":{
         "_id":"5f9c53c8a0db8f4240ec6f71",
         "code":"hkvt",
         "facultyName":"Space Airline"
      },
      "classSize":20,
      "warnedLength":10
   },
   {
      "faculty":{
         "_id":"5f9c53c8a0db8f4240ec6f71",
         "code":"hkvt",
         "facultyName":"Space Airline"
      },
      "classSize":30,
      "warnedLength":15
   }
]

and i want to have an output like this:

[
   {
      "faculty":{
         "_id":"5f9c3e04e5a5423cec34b2e2",
         "code":"khmt",
         "facultyName":"Computer Science"
      },
      "totalClassSize":91,
      "totalWarnedLength":61
   },
   {
      "faculty":{
         "_id":"5f9c53c8a0db8f4240ec6f71",
         "code":"dtvt",
         "facultyName":"Electronics and Telecommunication"
      },
      "totalClassSize":148, // total classSize of all class has facultyName is "Electronics and Telecommunication"
      "totalWarnedLength":64 // total warnedLength of all class has facultyName is "Electronics and Telecommunication"
   },
   {
      "faculty":{
         "_id":"5f9c53c8a0db8f4240ec6de0",
         "code":"hkvt",
         "facultyName":"Space Airline"
      },
      "totalClassSize":60, // total classSize of all class has facultyName is "Space Airline"
      "totalWarnedLength":30 // total warnedLength of all class has facultyName is "Space Airline"
   },
]

the output is an array, which sum all classSize has same faculty into property totalClassSize and sum all warnedLength has same faculty into property totalWarnedLength

the input is an array and the output still an array as well

i am a beginner in learning code and i am still stuck with this problem for while

thank you so much to help me out, have a good day

Answer

Using Array.prototype.reduce, you can generating new object by grouping the current input array by faculty._id as object key, and based on that, you can calculate the totalWarnedLength and totalClassSize for same object keys.

const input = [{
    "faculty": {
      "_id": "5f9c3e04e5a5423cec34b2e2",
      "code": "khmt",
      "facultyName": "Computer Science"
    },
    "classSize": 91,
    "warnedLength": 61
  },
  {
    "faculty": {
      "_id": "5f9c53c8a0db8f4240ec6f71",
      "code": "dtvt",
      "facultyName": "Electronics and Telecommunication"
    },
    "classSize": 89,
    "warnedLength": 44
  },
  {
    "faculty": {
      "_id": "5f9c53c8a0db8f4240ec6f71",
      "code": "dtvt",
      "facultyName": "Electronics and Telecommunication"
    },
    "classSize": 59,
    "warnedLength": 20
  },
  {
    "faculty": {
      "_id": "5f9c53c8a0db8f4240ec6f71",
      "code": "hkvt",
      "facultyName": "Space Airline"
    },
    "classSize": 10,
    "warnedLength": 5
  },
  {
    "faculty": {
      "_id": "5f9c53c8a0db8f4240ec6f71",
      "code": "hkvt",
      "facultyName": "Space Airline"
    },
    "classSize": 20,
    "warnedLength": 10
  },
  {
    "faculty": {
      "_id": "5f9c53c8a0db8f4240ec6f71",
      "code": "hkvt",
      "facultyName": "Space Airline"
    },
    "classSize": 30,
    "warnedLength": 15
  }
];

const groupBy = input.reduce((acc, cur) => {
  if (acc[cur.faculty['_id']]) {
    acc[cur.faculty['_id']].totalClassSize += cur.classSize;
    acc[cur.faculty['_id']].totalWarnedLength += cur.warnedLength;
  } else {
    acc[cur.faculty['_id']] = {
      faculty: cur.faculty,
      totalClassSize: cur.classSize,
      totalWarnedLength: cur.warnedLength
    };
  }
  return acc;
}, {});
const output = Object.values(groupBy);
console.log(output);
Advertisement