admin管理员组

文章数量:1389834

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);

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);

Share Improve this question edited Dec 13, 2018 at 3:20 Randy Casburn 14.2k1 gold badge19 silver badges32 bronze badges asked Dec 13, 2018 at 3:14 Anson CAnson C 5077 silver badges18 bronze badges 2
  • 1 So you're trying to sum the amount of a certain date you have? – Andrew Li Commented Dec 13, 2018 at 3:16
  • Yes, the sum of each date – Anson C Commented Dec 13, 2018 at 3:21
Add a ment  | 

4 Answers 4

Reset to default 5

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
  }
]
*/

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);

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);

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);

本文标签: javascriptES6 Sum by object property in an arrayStack Overflow