JS(ES6):基于对象属性减少数组

Posted

技术标签:

【中文标题】JS(ES6):基于对象属性减少数组【英文标题】:JS (ES6): Reduce array based on object attribute 【发布时间】:2018-09-29 19:05:27 【问题描述】:

我有一个这样的数组:

const fruits = [ 
     fruit: 'apple',  year: 2018 ,
     fruit: 'apple',  year: 2018 ,
     fruit: 'banana', year: 2018 ,
     fruit: 'orange', year: 2018 ,
     fruit: 'apple',  year: 2017 ,
     fruit: 'apple',  year: 2016 
];

现在我想减少这个数组,看看每年有多少水果,总数是多少。所以结果看起来像这样:

const result = [ 
     year: 2018, apple: 2, banana: 1, orange: 1 total: 4 ,
     year: 2017, apple: 1, total: 1 ,
     year: 2016, apple: 1, total: 1 
];

我尝试过使用 reduce,但我不知道如何根据年份对其进行分组。也许还有一个 lodash 助手?

【问题讨论】:

【参考方案1】:

使用Object.valuesreduce

var output = Object.values(fruits.reduce( (a,c) => 
  a[c.year] = a[c.year] ||  year : c.year ;  
  a[c.year]["total"] = (a[c.year]["total"] || 0) + 1;
  a[c.year][c.fruit] = (a[c.year][c.fruit] || 0) + 1;
  return a;
,));

演示

var fruits = [
    fruit: 'apple',
    year: 2018
  ,
  
    fruit: 'apple',
    year: 2018
  ,
  
    fruit: 'banana',
    year: 2018
  ,
  
    fruit: 'orange',
    year: 2018
  ,
  
    fruit: 'apple',
    year: 2017
  ,
  
    fruit: 'apple',
    year: 2016
  
];

var output = Object.values(fruits.reduce((a, c) => 
  a[c.year] = a[c.year] || 
    year: c.year
  ;
  a[c.year]["total"] = (a[c.year]["total"] || 0) + 1;
  a[c.year][c.fruit] = (a[c.year][c.fruit] || 0) + 1;
  return a;
, ));

console.log(output);

【讨论】:

【参考方案2】:

您可以使用array#reduce 根据年份对数据进行分组,并计算对象累加器中的水果出现次数。然后使用Object.values()从这个对象中获取所有值

const fruits = [  fruit: 'apple', year: 2018 ,  fruit: 'apple', year: 2018 ,  fruit: 'banana', year: 2018 ,  fruit: 'orange', year: 2018 ,  fruit: 'apple', year: 2017 ,  fruit: 'apple', year: 2016  ],
    result = Object.values(fruits.reduce((r,fruit, year) => 
      r[year] = r[year] || year;
      r[year][fruit] = (r[year][fruit] || 0) + 1;
      r[year]['total'] = (r[year]['total'] || 0) + 1;
      return r;
    ,));
console.log(result);

【讨论】:

【参考方案3】:

您可以使用数组作为结果集,它保持给定的年份顺序。

var fruits = [ fruit: 'apple',  year: 2018 ,  fruit: 'apple',  year: 2018 ,  fruit: 'banana', year: 2018 ,  fruit: 'orange', year: 2018 ,  fruit: 'apple',  year: 2017 ,  fruit: 'apple',  year: 2016 ],
    result = fruits.reduce((r,  year, fruit ) => 
        var item = r.find(o => o.year === year);
        if (!item) 
            r.push(item =  year );
        
        item[fruit] = (item[fruit] || 0) + 1;
        return r;
    , []);
    
console.log(result);
.as-console-wrapper  max-height: 100% !important; top: 0; 

【讨论】:

以上是关于JS(ES6):基于对象属性减少数组的主要内容,如果未能解决你的问题,请参考以下文章

ES6中的数组

es6中的数组循环和对象方法

关于ES6的flat(扁平化数组)

ES6 解构赋值

ES6对象的新增方法

Js es6中扩展运算符(...)