Skip to content Skip to sidebar Skip to footer

Es6 Sum By Object Property In An Array

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 h

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

Solution 2:

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

Solution 3:

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

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

Post a Comment for "Es6 Sum By Object Property In An Array"