Home > database >  Group object keys values in order to obtain a list of objects grouped by a key
Group object keys values in order to obtain a list of objects grouped by a key

Time:06-10

I have an object like:

{
"Account Management": [
    {
        "rowId": 1288,
        "departmentExternalId": "7",
        "departmentName": "Account Management",
        "measureName": "Total Headcount Expense",
        "measureId": 15,
        "measureValue": 17282,
    },
    {
        "rowId": 1289,
        "departmentExternalId": "7",
        "departmentName": "Account Management",
        "measureName": "Salary",
        "measureId": 5,
        "measureValue": 11666,
    },
],
"Client Services General (COR)": [
    {
        "rowId": 1294,
        "departmentExternalId": "114",
        "departmentName": "Client Services General (COR)",
        "measureName": "Total Headcount",
        "measureId": 2,
        "measureValue": 1,
    },
    {
        "rowId": 1295,
        "departmentExternalId": "114",
        "departmentName": "Client Services General (COR)",
        "measureName": "Total Headcount",
        "measureId": 2,
        "measureValue": 100,
    }
]
}

Each object key represents the department, object obtained after grouping the data got from BE. Now I need to group each object inside department by measureId and count them to obtain something like:

[
  {department: "Account Management", measure15: 17282, measure5: 11666},
  {department: "Client Services General (COR)", measure2: 101}
]

I tried to group the grouped by department data again by measureId, but I here I have a blocker and don't know how to continue.

If anybody has any idea, please tell me.

Thanks in advance!

CodePudding user response:

The logic is to create an array of objects that store the

[{measureX: sumOfValuesX}, {measureY: sumOfValuesY, ...}] 

For each specific id of the corresponding department. Then, by destructuring the object and combining it with Object.assign(), you can flat that whole array and have all values available.

As seen in this approach with additional use of Object.entries() and reduce():

let obj={"Account Management":[{rowId:1288,departmentExternalId:"7",departmentName:"Account Management",measureName:"Total Headcount Expense",measureId:15,measureValue:17282},{rowId:1289,departmentExternalId:"7",departmentName:"Account Management",measureName:"Salary",measureId:5,measureValue:11666},],"Client Services General (COR)":[{rowId:1294,departmentExternalId:"114",departmentName:"Client Services General (COR)",measureName:"Total Headcount",measureId:2,measureValue:1},{rowId:1295,departmentExternalId:"114",departmentName:"Client Services General (COR)",measureName:"Total Headcount",measureId:2,measureValue:100}]}

output = Object.entries(obj).map(([key, value]) => ({
    "department": key,
    ...Object.assign(...value.reduce((acc, curr) => {
        let currId = acc.filter(x => x[`measure${curr.measureId}`])
        if (currId.length) {
            currId[0][`measure${curr.measureId}`]  = curr.measureValue
            return acc
        } else {
            return [...acc, { [`measure${curr.measureId}`]: curr.measureValue }]
        }
    }, [])) 
}))

console.log(output)

CodePudding user response:

By using the function Array.prototype.reduce we can create an object with keys equal to the departmentNames, and then we can extract the objects as an array with the function Object.values.

Finally, by using the function Array.prototype.flatMap we can transform an array of arrays into a simple array.

const obj = {  "Account Management": [{    rowId: 1288,    departmentExternalId: "7",    departmentName: "Account Management",    measureName: "Total Headcount Expense",    measureId: 15,    measureValue: 17282  }, {    rowId: 1289,    departmentExternalId: "7",    departmentName: "Account Management",    measureName: "Salary",    measureId: 5,    measureValue: 11666  }, ],  "Client Services General (COR)": [{    rowId: 1294,    departmentExternalId: "114",    departmentName: "Client Services General (COR)",    measureName: "Total Headcount",    measureId: 2,    measureValue: 1  }, {    rowId: 1295,    departmentExternalId: "114",    departmentName: "Client Services General (COR)",    measureName: "Total Headcount",    measureId: 2,    measureValue: 100  }]},
      output = Object.values(obj).flatMap((array) => {
        return Object.values(array.reduce((a, d) => {
          const currentMeasure = a[d.departmentName]?.[`measure${d.measureId}`];

          a[d.departmentName] = {...(a[d.departmentName] || {department: d.departmentName}), [`measure${d.measureId}`]: (currentMeasure || 0)   d.measureValue};
          return a;
        }, {}));
      });

console.log(output);
.as-console-wrapper { max-height: 100% !important; top: 0; }

  • Related