分组并计算Javascript数组中的属性均值/平均值 [英] Group by and calculate mean / average of properties in a Javascript array

查看:418
本文介绍了分组并计算Javascript数组中的属性均值/平均值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

即使我强烈认为必须存在该解决方案,我仍在其他stackoverflow帖子中努力寻找所需的解决方案.如果是这样,请按照正确的方向转发我.

I struggled finding the solution I was looking for in other stackoverflow posts, even though I strongly feel as if it must exist. If it does, please do forward me in the right direction.

我正在尝试使用体育数据在javascript中进行标准分组.我有以下对象数组:

I am trying to do a pretty standard group by in javascript using sports data. I have the following array of objects:

 const myData = [
    {team: "GSW", pts: 120, ast: 18, reb: 11},
    {team: "GSW", pts: 125, ast: 28, reb: 18},
    {team: "GSW", pts: 110, ast: 35, reb: 47},
    {team: "HOU", pts: 100, ast: 17, reb: 43},
    {team: "HOU", pts: 102, ast: 14, reb: 32},
    {team: "SAS", pts: 127, ast: 21, reb: 25},
    {team: "SAS", pts: 135, ast: 25, reb: 37},
    {team: "SAS", pts: 142, ast: 18, reb: 27}
 ]

我的数据中的每一行都对应于特定篮球比赛的结果.简而言之,我想对数据进行分组,并对分组后的数据应用均值/平均函数.我期望的结果是:

Each row in my data corresponds to the results of a specific basketball game. Simply put, I would like to group by the data, and apply a mean/average function to the grouped data. The results I would expect are:

const groupedData = [
    {team: "GSW", pts: 118.3, ast: 27.0, reb: 25.3},
    {team: "HOU", pts: 101, ast: 15.5, reb: 37.5},
    {team: "SAS", pts: 134.7, ast: 21.3, reb: 29.7} 
] 

我更喜欢在此处使用带有reduce()的原始javascript ...鉴于我对reduce的了解,这似乎是最好的方法.我目前正在研究此问题,如果有人可以在别人发布答案之前将其投入使用,我会在此发布.

I would prefer to use vanilla javascript with reduce() here... given what I know about reduce, it seems like the best way. I am currently working on this and will post if i can get it to work before someone else posts the answer.

我的实际数据有大约30个键.我希望找到一个解决方案,简单地要求我要么(a)仅指定要分组的团队"列,然后假设将其余的分组,要么(b)传递一组统计列(点,资产等). ),而不是为每个统计信息创建一行.

My actual data has ~30 keys. I am hoping to find a solution that simply asks me to either (a) specify only the team column to be grouped by, and assume it groups the rest, or (b) pass an array of stat columns (pts, asts, etc.) rather than creating a line for each stat.

谢谢!

推荐答案

一种方法是结合使用reducemap.

One way to do this is to use reduce and map in conjunction.

const myData = [
    {team: "GSW", pts: 120, ast: 18, reb: 11},
    {team: "GSW", pts: 125, ast: 28, reb: 18},
    {team: "GSW", pts: 110, ast: 35, reb: 47},
    {team: "HOU", pts: 100, ast: 17, reb: 43},
    {team: "HOU", pts: 102, ast: 14, reb: 32},
    {team: "SAS", pts: 127, ast: 21, reb: 25},
    {team: "SAS", pts: 135, ast: 25, reb: 37},
    {team: "SAS", pts: 142, ast: 18, reb: 27}
 ]
 
 // Calculate the sums and group data (while tracking count)
 const reduced = myData.reduce(function(m, d){
    if(!m[d.team]){
      m[d.team] = {...d, count: 1};
      return m;
    }
    m[d.team].pts += d.pts;
    m[d.team].ast += d.ast;
    m[d.team].reb += d.reb;
    m[d.team].count += 1;
    return m;
 },{});
 
 // Create new array from grouped data and compute the average
 const result = Object.keys(reduced).map(function(k){
     const item  = reduced[k];
     return {
         team: item.team,
         ast: item.ast/item.count,
         pts: item.pts/item.count,
         reb: item.reb/item.count
     }
 })
 
 console.log(JSON.stringify(result,null,4));

刚刚看到您对问题的更新.如果您可以将白名单(提供要计算的键数组)或黑名单(提供要忽略的键数组)以编程方式做到这一点,则可以省去每个键的每一行.

Just saw your update to the question. You can do away with each line for each key if you can either whitelist (provide an array of keys to compute) or blacklist (provide an array of keys to ignore) keys to do that programmatically.

const myData = [
    {team: "GSW", pts: 120, ast: 18, reb: 11},
    {team: "GSW", pts: 125, ast: 28, reb: 18},
    {team: "GSW", pts: 110, ast: 35, reb: 47},
    {team: "HOU", pts: 100, ast: 17, reb: 43},
    {team: "HOU", pts: 102, ast: 14, reb: 32},
    {team: "SAS", pts: 127, ast: 21, reb: 25},
    {team: "SAS", pts: 135, ast: 25, reb: 37},
    {team: "SAS", pts: 142, ast: 18, reb: 27}
 ]
 
/**
 * Function which accepts a data array and a list of whitelisted
 * keys to find the average of each key after grouping
 */
function getGroupedData(data, whitelist) {
  // Calculate the sums and group data (while tracking count)
  const reduced = data.reduce(function(m, d) {
    if (!m[d.team]) {
      m[d.team] = { ...d,
        count: 1
      };
      return m;
    }
    whitelist.forEach(function(key) {
      m[d.team][key] += d[key];
    });
    m[d.team].count += 1;
    return m;
  }, {});

  // Create new array from grouped data and compute the average
  return Object.keys(reduced).map(function(k) {
    const item = reduced[k];
    const itemAverage = whitelist.reduce(function(m, key) {
      m[key] = item[key] / item.count;
      return m;
    }, {})
    return {
      ...item, // Preserve any non white-listed keys
      ...itemAverage // Add computed averege for whitelisted keys
    }
  })
}


console.log(JSON.stringify(getGroupedData(myData, ['pts', 'ast', 'reb']), null, 4));

这篇关于分组并计算Javascript数组中的属性均值/平均值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆