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.