简体   繁体   English

分组对象键值以获得按键分组的对象列表

[英]Group object keys values in order to obtain a list of objects grouped by a key

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.每个对象键代表部门,从BE得到的数据分组后得到的对象。 Now I need to group each object inside department by measureId and count them to obtain something like:现在我需要通过measureId对部门内的每个对象进行分组并计算它们以获得如下内容:

[
  {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.我尝试通过 measureId 再次对按部门分组的数据进行分组,但我这里有一个阻止程序,不知道如何继续。

If anybody has any idea, please tell me.如果有人有任何想法,请告诉我。

Thanks in advance!提前致谢!

The logic is to create an array of objects that store the逻辑是创建一个对象数组来存储

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

For each specific id of the corresponding department.对于相应部门的每个特定 id。 Then, by destructuring the object and combining it with Object.assign() , you can flat that whole array and have all values available.然后,通过解构对象并将其与Object.assign()组合,您可以将整个数组展平并获得所有可用值。

As seen in this approach with additional use of Object.entries() and reduce() :正如在这种方法中看到的那样,额外使用了Object.entries()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, {measureId, measureValue} ) => { let measureIdKey = `measure${measureId}` let currId = acc.filter(x => x[measureIdKey]) return (currId.length ? (currId[0][measureIdKey] += measureValue , acc) : [...acc, { [measureIdKey]: measureValue }]) }, [])) })) console.log(output)

In Typescript, it has some modifications to follow the typing stuff.在 Typescript 中,它进行了一些修改以遵循打字内容。

type Info = {
    measureValue: string;
    measureId: number;
}

type Foo = { [key: string]: string | number; } 

type Department = {
    rowId: number;
    departmentExternalId: string;
    departmentName: string;
    measureName: string;
    measureValue: number;
} | Info


let output = Object.entries(obj).map(([key, value]) => ({
    "department": key,
    ...applyReduce(value as Info[])
})) 
 
function applyReduce(foo: Info[]) {
    return foo.reduce((acc: Info[], { measureValue, measureId }: Info): any => {
        let measureIdKey = `measure${measureId}`

        let currId: Foo[] = []  // this line is needed to compile
        acc.forEach(x => currId.push(x)) // this line too

        currId = currId.filter(x => x[measureIdKey])
        return (currId.length ?
            (currId[0][measureIdKey] += measureValue
                , acc) : [...acc, { [measureIdKey]: measureValue }])
    }, []).reduce((a, c) => ({...a,...c}), {})  // added another reduce
} 

console.log(output)

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 .通过使用Array.prototype.reduce函数,我们可以创建一个键等于部门名称的对象,然后我们可以使用函数Object.values将对象提取为一个数组。

Finally, by using the function Array.prototype.flatMap we can transform an array of arrays into a simple array.最后,通过使用Array.prototype.flatMap函数,我们可以将数组数组转换为简单数组。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM