问题
I am trying to sum the unit value by date, and create a new array where there are no duplicate dates. For example, I want to calculate the total of 2015-12-04 00:01:00
. This date has occurred 2 times in the following data, its value is 5
and 6
, which is going to be:
[{date: '2015-12-04 00:01:00', unit: 11}, ... etc]
I have tried arr = results.map(x => x.unit).reduce((a,c) => a + c)
but it only return a single value, not an array.
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:
You can reduce your data to a dictionary and then map it to an array like so
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
}
]
*/
回答2:
you should group by date in a new element and then create a new array with the sum of units
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);
回答3:
You need to make the accumulator in reduce
an object whose keys are the dates. Then you can accumulate in the units
property.
You can use Object.values()
to convert this back to an array.
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);
回答4:
I think you want this?
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);
来源:https://stackoverflow.com/questions/53754524/es6-sum-by-object-property-in-an-array