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; }