如何在ES6中使用reduce()来计算平均值?

时间:2018-06-20 11:10:18

标签: javascript ecmascript-6

我正在尝试从JSON数据中提取econseason(请参见下面的屏幕截图)。我想找到每个季节的平均经济率

例如:season = 2018 economy rate = 10,20,30 so avg economy rate = (10+20+30)/3 = 20

season = 2017 economy rate = 30,40,50 so avg economy rate = (30+40+50)/3 = 40

所以我想计算特定季节的所有经济费率之和,然后取平均值,即特定季节的总和除以该季节的比赛次数。

下面是我试图在ES6中使用reduce()的代码:

const economy = bowldata.reduce( (a,{season, econ})  => {
                    a[season] = a[season] + parseInt(econ);
                    return a; 
                }, {});
console.log(economy);

我得到2018:NaN,但我希望输出为2018:22,2017:50等,即我想要季节的关键值对和该季节的平均经济增长率。

屏幕截图:

enter image description here

假设我有JSON数据:

var bowldata = [
    {
        season:2018
        economy:10
    },
    {   season:2018
        economy:20
    },
    {   season:2018
        economy:30
    },
    {   season:2017
        economy:40
    },
    {   season:2017
        economy:50
    },
    {   season:2016
        economy:10
    },
]

现在reduce()应该返回的对象是年份和平均经济率的键值对。

结果:[ 2018:20 , 2017:45 , 2016:10 ]

5 个答案:

答案 0 :(得分:2)

更改

a[season] = a[season] + parseInt(econ);

收件人

a[season] = (a[season] || 0 ) + parseInt(econ);

这将说明尚未设置该属性的第一个实例,因此当未定义该属性时,您会将新值添加为零。

答案 1 :(得分:2)

由于要计算平均值,因此可以将对象作为任何季节的默认值。为此,您还需要计数。

var bowldata = [{ season: 2001, econ: '30' }, { season: 2001, econ: '40' }, { season: 2001, econ: '50' }, { season: 2001, econ: '60' }, { season: 2002, econ: '30' }, { season: 2002, econ: '40' }, { season: 2002, econ: '50' }, { season: 2003, econ: '60' }, { season: 2003, econ: '30' }, { season: 2003, econ: '40' }, { season: 2003, econ: '50' }, { season: 2003, econ: '60' }],
    economy = bowldata.reduce((a, { season, econ }) => {
        a[season] = a[season] || { sum: 0, count: 0 };
        a[season].sum += +econ;
        a[season].average = a[season].sum / ++a[season].count;
        return a;
    }, Object.create(null)),
    nice = Object.assign(...Object
        .entries(economy)
        .map(([k, { average }]) => ({ [k]: average }))
    );

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

答案 2 :(得分:1)

第一次执行a[season] = a[season] + parseInt(econ);时,a[season]未定义。只需使用0对其进行初始化就可以对其进行初始化。

const economy = bowldata.reduce( (a,{season, econ})  => {
    if (!a[season]) {
        a[season] = 0;
    }
    a[season] = a[season] + parseInt(econ);
    return a; 
}, {});

答案 3 :(得分:1)

要计算平均值而不是总计,最好通过两步过程为您服务,如下所示:

const totals = bowldata.reduce((acc, cur)  => {

  if (!acc[cur.season]) {
    acc[cur.season] = {count: 0, total: 0};
  }

  acc[cur.season].count++;
  acc[cur.season].total += parseInt(cur.econ);

  return acc; 
}, {});

const averages = {};

Object.keys(totals).forEach(key => {

  averages[key] = totals[key].total / totals[key].count;

});

答案 4 :(得分:1)

     Hi you can solve the problem by following chain of reduce and map:   
 i) Reduce to season and economies aggregation   
 ii) Map to get season and avg economy   
 iii)Map to get the season and economy  key value string   

bowldata.reduce((acc,b)=>{ const y =acc.find(x => x.s ===b.s); y? y.e.push(b.e) :acc.push({s:b.s, e:[b.e]}); return acc },[])
.map(x => ({s:x.s,e:x.e.reduce((acc,b,i)=> (acc*i + parseInt(b))/(i+1),0)})
)
.map( x=> (x.s +':' + x.e))