Categories
discuss

ES6 Nested Grouping with Sum

I have an array like this: [{ id: 1, amount: 10, date: ’21/01/2017′ },{ id: 1, amount: 10, date: ’21/01/2017′ },{ id: 1, amount: 30, date: ’22/01/2017′ },{ id: 2, …

I have an array like this:

[{
   id: 1,
   amount: 10,
   date: '21/01/2017'
},{
   id: 1,
   amount: 10,
   date: '21/01/2017'
},{
   id: 1,
   amount: 30,
   date: '22/01/2017'
},{
   id: 2,
   amount: 10,
   date: '21/01/2017'
},]

And I would like this to output like:

{
  '21/01/2017': {
    1: {
      amount: 20
    },
    2: {
      amount: 10
    }
  },
  '22/01/2017': {
    1: {
      amount: 30
    }
  }
}

Essentially grouping by data, nested grouping by id, whilst summing the relevant amounts.

So far I have tried using reduce, and have looked at lodash functions but have been unsuccessful. Reduce makes it easy to group by and sum by one prop, but I cannot find an elegant way to create the second level. I have created the a sandbox to demonstrate:

https://codesandbox.io/s/woj9xz6nq5

const dataToConsolidate = [{
  id: 1,
  amount: 10,
  date: '21/01/2017'
}, {
  id: 1,
  amount: 10,
  date: '21/01/2017'
}, {
  id: 1,
  amount: 30,
  date: '22/01/2017'
}, {
  id: 2,
  amount: 10,
  date: '21/01/2017'
},]

export const consolidate = (data) => {
  const result = data.reduce(function (res, obj) {

    (!(obj.date in res)) ?
      res.__array.push(res[obj.date] = obj) :
      res[obj.date].amount += obj.amount;

    return res;
  }, { __array: [] });

  return result;
};

console.log(consolidate(dataToConsolidate))

Answer

Here’s a relatively ES6-y solution using reduce:

const initial = [{ id: 1, amount: 10, date: '21/01/2017' }, { id: 1, amount: 10, date: '21/01/2017' }, { id: 1, amount: 30, date: '22/01/2017' }, { id: 2, amount: 10, date: '21/01/2017' }];

const parse = obj => obj.reduce((final, { date, id, amount }) => {
  let group = final[date] = final[date] || {};
  group[id] = group[id] || { amount: 0 };
  group[id].amount += amount;
  return final;
}, {});

const final = parse(initial);
console.log(final);

You’ll want to add appropriate logic to handle missing/erroneous date, id, or amount keys.

Source: stackoverflow
Text is available under the Creative Commons Attribution-ShareAlike License; additional terms may apply. By using this site, you agree to the Privacy Policy, and Copyright Policy. Content is available under CC BY-SA 3.0 unless otherwise noted. The answers/resolutions are collected from stackoverflow, are licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0 © No Copyrights, All Questions are retrived from public domain..