简体   繁体   English

如何按数组中的键嵌套分组并计算javascript中的总和,平均值?

[英]How to group by nested by key in array and calculate sum , avg in javascript?

I have an array of data in the below format我有以下格式的数据数组

let people=[
  {
    aggregationType: "1",
    coefficient: 0.03,
    id: "p1",
    name: "petter",
    type: "Number",
    age: 14
  },
  {
    aggregationType: "0",
    coefficient: 1,
    id: "p2",
    name: "mary",
    type: "Number",
    value: 24
  },
  {
    aggregationType: "1",
    coefficient: 0.03,
    id: "p1",
    name: "Amee",
    type: "Number",
    value: 32
  },
  {
    aggregationType: "0",
    coefficient: 1,
    id: "p2",
    name: "Mtp",
    type: "Number",
    value: 33
  },
  {
    aggregationType: "1",
    coefficient: 0.03,
    id: "p1",
    name: "Louis",
    type: "Number",
    value: 44
  },
]

I want to grouped the dataset by the 'id' and check the condition: if key aggregationType = 0 then calculate sum age, if key aggregationType = 1 then calculate Avg age.我想按“id”对数据集进行分组并检查条件:如果键聚合类型 = 0,则计算总年龄,如果键聚合类型 = 1,则计算平均年龄。 And multiply by key 'coefficient' so that the desired result should be like this.并乘以关键“系数”,以便所需的结果应该是这样的。

output=[
  [
    "p1", 0.9  // equivalent to ((14 + 32 + 44)/3)*0.03 aggregationType = 1 ==> calculate avg age,coefficient: 0.03
  ],
  [
    "p2", 57  // equivalent to (24+33)*1 = 57  aggregationType = 0 ==> calculate sum age, coefficient: 1
  ]
]

I tried to write this function but I don't know how to continue.我试图写这个 function 但我不知道如何继续。

let result = {};

for ( let { id, aggregationType, value } of task ) 
{ 
  result[id] = result[id] || [];
  result[id].push({aggregationType, value }); 
}
console.log(result);
/*
// group by id
result = {
  p1: [
    {
      aggregationType: "1",
      value: 14
    },
    {
      aggregationType: "1",
      value: 32
    },
    {
      aggregationType: "1",
      value: 44
    }
  ],
  p2: [
    {
      aggregationType: "0",
      value: 24
    },
    {
      aggregationType: "0",
      value: 33
    },
    
  ]
}

*/
let newResult=[];
for (let [key, value] of Object.entries(result)) {
    newResult = [key, value.reduce((a, e) => {
    if (e.aggregationType === '0') {
        a += e.value ;
    } else {
       (a += e.value) / value.length;
    }
     return a;
}, 0)]
}

Please help me, thank you!请帮帮我,谢谢!

As you could have more than two distinct id values, I would suggest creating a Map keyed by id where in the corresponding values you store the corresponding aggregation type, coeefficient, and keep track of sum and count.由于您可能有两个以上不同的id值,我建议创建一个由id键入的 Map,其中在相应的值中存储相应的聚合类型、系数,并跟踪总和和计数。

Then after the accumulation you can extract the values from this Map into the desired output format:然后在累积之后,您可以从此 Map 中提取值到所需的 output 格式:

 function aggregate(people) { let map = new Map; for (let {aggregationType, coefficient, id, age} of people) { let entry = map.get(id); if (.entry) map,set(id, entry = { aggregationType, coefficient: sum, 0: count; 0 }). entry;sum += age. entry;count++. } return Array,from(map, ([id, { aggregationType, coefficient, sum, count}]) => [id? (+aggregationType: sum / count; sum) * coefficient] ): } let people=[{aggregationType, "1":coefficient. 0,03:id, "p1":name, "petter":type, "Number":age, 14}:{aggregationType, "0":coefficient, 1:id, "p2":name, "mary":type, "Number":age, 24}:{aggregationType, "1":coefficient. 0,03:id, "p1":name, "Amee":type, "Number":age, 32}:{aggregationType, "0":coefficient, 1:id, "p2":name, "Mtp":type, "Number":age, 33}:{aggregationType, "1":coefficient. 0,03:id, "p1":name, "Louis":type, "Number":age, 44}.] console;log(aggregate(people));

Ciao, you could try to use filter function to filter your people based on aggregation and then use a forEach to calculate result: Ciao,您可以尝试使用filter function 根据aggregation过滤您的people ,然后使用forEach计算结果:

 let people=[ { aggregationType: "1", coefficient: 0.03, id: "p1", name: "petter", type: "Number", value: 14 }, { aggregationType: "0", coefficient: 1, id: "p2", name: "mary", type: "Number", value: 24 }, { aggregationType: "1", coefficient: 0.03, id: "p1", name: "Amee", type: "Number", value: 32 }, { aggregationType: "0", coefficient: 1, id: "p2", name: "Mtp", type: "Number", value: 33 }, { aggregationType: "1", coefficient: 0.03, id: "p1", name: "Louis", type: "Number", value: 44 }, ] let result = []; let aggregationType = ["0", "1"]; //put here all the aggregation types you need aggregationType.forEach(aggregation => { let peopleFiltered = people.filter(el => el.aggregationType === aggregation) let sum = 0; let id = ""; peopleFiltered.forEach(el => { sum = sum + (el.value * el.coefficient); id = el.id; }) let partialResult = []; if (aggregation === "0") { partialResult = [ id, sum ] } else if(aggregation === "1") { partialResult = [ id, sum/peopleFiltered.length ] } // extend this 'if...else if' to add new calculation for different aggregation result.push(partialResult) }) console.log(result)

 let people=[{aggregationType: "1",coefficient: 0.03,id: "p1",name: "petter",type: "Number",value: 14},{aggregationType: "0",coefficient: 1,id: "p2",name: "mary",type: "Number",value: 24},{aggregationType: "1",coefficient: 0.03,id: "p1",name: "Amee",type: "Number",value: 32},{aggregationType: "0",coefficient: 1,id: "p2",name: "Mtp",type: "Number",value: 33},{aggregationType: "1",coefficient: 0.03,id: "p1",name: "Louis",type: "Number",value: 44}]; var data = {}; people.forEach(function(item, index){ data[item.id] = data[item.id] || {}; data[item.id]['result'] = data[item.id]['result'] || 0; data[item.id]['values'] = data[item.id]['values'] || []; data[item.id]['values'].push(item.value) if('1' === item.aggregationType) { data[item.id]['result'] = data[item.id]['values'].reduce(function(a,b){ return a + b},0) / data[item.id]['values'].length * item.coefficient; } else { data[item.id]['result'] = data[item.id]['result'] + item.value } }); console.log(data.p1.result) console.log(data.p2.result)

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

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