ES6通过数组中的对象属性求和
Posted
技术标签:
【中文标题】ES6通过数组中的对象属性求和【英文标题】:ES6 Sum by object property in an array 【发布时间】:2019-05-14 05:41:20 【问题描述】:我正在尝试按日期对单位值求和,并创建一个没有重复日期的新数组。例如,我想计算2015-12-04 00:01:00
的总数。该日期在以下数据中出现了 2 次,其值为5
和6
,分别为:
[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}的求和