ES6通过数组中的对象属性求和

Posted

技术标签:

【中文标题】ES6通过数组中的对象属性求和【英文标题】:ES6 Sum by object property in an array 【发布时间】:2019-05-14 05:41:20 【问题描述】:

我正在尝试按日期对单位值求和,并创建一个没有重复日期的新数组。例如,我想计算2015-12-04 00:01:00 的总数。该日期在以下数据中出现了 2 次,其值为56,分别为:

[date: '2015-12-04 00:01:00', unit: 11, ... etc]

我试过arr = results.map(x => x.unit).reduce((a,c) => a + c),但它只返回一个值,而不是一个数组。

results = [  unit: 5, date: '2015-12-04 00:01:00' ,
           unit: 10, date: '2015-12-04 00:01:00' ,
           unit: 5, date: '2015-12-04 00:31:00' ,
           unit: 9, date: '2015-12-04 00:31:00' ,
           unit: 5, date: '2015-12-04 01:01:00' ,
           unit: 10, date: '2015-12-04 01:01:00' ,
           unit: 10, date: '2015-12-04 01:31:00' ,
           unit: 5, date: '2015-12-04 01:31:00' ,
           unit: 10, date: '2015-12-04 02:01:00' ,
           unit: 5, date: '2015-12-04 02:01:00' ,
           unit: 5, date: '2015-12-04 02:31:00' ,
           unit: 9, date: '2015-12-04 02:31:00' ,
           unit: 5, date: '2015-12-04 03:01:00' ,
           unit: 9, date: '2015-12-04 03:01:00' ,
           unit: 5, date: '2015-12-04 03:31:00' ,
           unit: 10, date: '2015-12-04 03:31:00' ,
           unit: 10, date: '2015-12-04 04:01:00' ,
           unit: 5, date: '2015-12-04 04:01:00' ];

arr = results.map(x => x.unit).reduce((a,c) => a + c);
console.log(arr);

【问题讨论】:

所以你想总结你拥有的某个日期的数量? 是的,每个日期的总和 【参考方案1】:

你应该在一个新元素中按日期分组,然后用单位总和创建一个新数组

let indexedDates = ;
results.forEach(result => 
   let arrayByDate = indexedDates[result.date] || [];
   arrayByDate.push(result.unit);
   indexedDates[result.date] = arrayByDate;
);
let yourExpectedResult = Object.keys(indexedDates).map(date => (
  date,
  unit: indexedDates[date].reduce((a, b) => a +b)
));

let results = [  unit: 5, date: '2015-12-04 00:01:00' ,
       unit: 10, date: '2015-12-04 00:01:00' ,
       unit: 5, date: '2015-12-04 00:31:00' ,
       unit: 9, date: '2015-12-04 00:31:00' ,
       unit: 5, date: '2015-12-04 01:01:00' ,
       unit: 10, date: '2015-12-04 01:01:00' ,
       unit: 10, date: '2015-12-04 01:31:00' ,
       unit: 5, date: '2015-12-04 01:31:00' ,
       unit: 10, date: '2015-12-04 02:01:00' ,
       unit: 5, date: '2015-12-04 02:01:00' ,
       unit: 5, date: '2015-12-04 02:31:00' ,
       unit: 9, date: '2015-12-04 02:31:00' ,
       unit: 5, date: '2015-12-04 03:01:00' ,
       unit: 9, date: '2015-12-04 03:01:00' ,
       unit: 5, date: '2015-12-04 03:31:00' ,
       unit: 10, date: '2015-12-04 03:31:00' ,
       unit: 10, date: '2015-12-04 04:01:00' ,
       unit: 5, date: '2015-12-04 04:01:00' ];
let indexedDates = ;
results.forEach(result => 
   let arrayByDate = indexedDates[result.date] || [];
   arrayByDate.push(result.unit);
   indexedDates[result.date] = arrayByDate;
);
let yourExpectedResult = Object.keys(indexedDates).map(date => (
  date,
  unit: indexedDates[date].reduce((a, b) => a +b)
));
console.log(yourExpectedResult);

【讨论】:

【参考方案2】:

您可以将数据简化为字典,然后将其映射到这样的数组

results = [  unit: 5, date: '2015-12-04 00:01:00' ,
       unit: 10, date: '2015-12-04 00:01:00' ,
       unit: 5, date: '2015-12-04 00:31:00' ,
       unit: 9, date: '2015-12-04 00:31:00' ,
       unit: 5, date: '2015-12-04 01:01:00' ,
       unit: 10, date: '2015-12-04 01:01:00' ,
       unit: 10, date: '2015-12-04 01:31:00' ,
       unit: 5, date: '2015-12-04 01:31:00' ,
       unit: 10, date: '2015-12-04 02:01:00' ,
       unit: 5, date: '2015-12-04 02:01:00' ,
       unit: 5, date: '2015-12-04 02:31:00' ,
       unit: 9, date: '2015-12-04 02:31:00' ,
       unit: 5, date: '2015-12-04 03:01:00' ,
       unit: 9, date: '2015-12-04 03:01:00' ,
       unit: 5, date: '2015-12-04 03:31:00' ,
       unit: 10, date: '2015-12-04 03:31:00' ,
       unit: 10, date: '2015-12-04 04:01:00' ,
       unit: 5, date: '2015-12-04 04:01:00' ]

// first make an object with date: unit value as such
const newResults = results.reduce((acc, item) => (
  ...acc,
  [item.date]: (acc[item.date] || 0) + item.unit
) , )

console.log(newResults)
/*

  "2015-12-04 00:01:00": 15,
  "2015-12-04 00:31:00": 14,
  "2015-12-04 01:01:00": 15,
  "2015-12-04 01:31:00": 15,
  "2015-12-04 02:01:00": 15,
  "2015-12-04 02:31:00": 14,
  "2015-12-04 03:01:00": 14,
  "2015-12-04 03:31:00": 15,
  "2015-12-04 04:01:00": 15

*/

// now if you want array representation for this you can do

const finalResult = Object.keys(newResults).map(key => (date: key, unit: newResults[key]))

console.log(finalResult)
/*
[
  
    "date": "2015-12-04 00:01:00",
    "unit": 15
  ,
  
    "date": "2015-12-04 00:31:00",
    "unit": 14
  ,
  
    "date": "2015-12-04 01:01:00",
    "unit": 15
  ,
  
    "date": "2015-12-04 01:31:00",
    "unit": 15
  ,
  
    "date": "2015-12-04 02:01:00",
    "unit": 15
  ,
  
    "date": "2015-12-04 02:31:00",
    "unit": 14
  ,
  
    "date": "2015-12-04 03:01:00",
    "unit": 14
  ,
  
    "date": "2015-12-04 03:31:00",
    "unit": 15
  ,
  
    "date": "2015-12-04 04:01:00",
    "unit": 15
  
]
*/

【讨论】:

【参考方案3】:

我想你想要这个?

const x = results.reduce((accu, r) => 
    const  unit, date  = r;
    accu[date] = accu[date] ||  unit: 0, date ;
    accu[date].unit += unit;
    return accu;
, );
const yourNeed = Object.values(x);

【讨论】:

【参考方案4】:

您需要将reduce 中的累加器设为键为日期的对象。然后就可以在units属性中积累了。

您可以使用Object.values() 将其转换回数组。

results = [  unit: 5, date: '2015-12-04 00:01:00' ,
           unit: 10, date: '2015-12-04 00:01:00' ,
           unit: 5, date: '2015-12-04 00:31:00' ,
           unit: 9, date: '2015-12-04 00:31:00' ,
           unit: 5, date: '2015-12-04 01:01:00' ,
           unit: 10, date: '2015-12-04 01:01:00' ,
           unit: 10, date: '2015-12-04 01:31:00' ,
           unit: 5, date: '2015-12-04 01:31:00' ,
           unit: 10, date: '2015-12-04 02:01:00' ,
           unit: 5, date: '2015-12-04 02:01:00' ,
           unit: 5, date: '2015-12-04 02:31:00' ,
           unit: 9, date: '2015-12-04 02:31:00' ,
           unit: 5, date: '2015-12-04 03:01:00' ,
           unit: 9, date: '2015-12-04 03:01:00' ,
           unit: 5, date: '2015-12-04 03:31:00' ,
           unit: 10, date: '2015-12-04 03:31:00' ,
           unit: 10, date: '2015-12-04 04:01:00' ,
           unit: 5, date: '2015-12-04 04:01:00' ];

arr = Object.values(results.reduce((a, 
  unit,
  date
) => (a[date] = 
  date: date,
  unit: a[date] ? a[date].unit + unit : unit
, a), ));
console.log(arr);

【讨论】:

以上是关于ES6通过数组中的对象属性求和的主要内容,如果未能解决你的问题,请参考以下文章

javascript es6 多维数组对象相同属性值{key:value}的求和

javascript es6 多维数组对象相同属性值{key:value}的求和

如何通过特定对象键对数组中的值求和?

ES6中的类和对象继承

ES6中的类和对象继承

如何使用 AngularJs 对对象数组中的属性值求和