Reputation: 13
I have the following array filled with some objects:
const data = [
{date: '8 - 2021', 'a20 - plan1': 20, 'b70 - plan1': 10, 'c30 - plan1': 5},
{date: '9 - 2021', 'a20 - plan1': 60, 'b70 - plan1': 70, 'c30 - plan1': 20},
{date: '8 - 2021', 'a20 - plan1': 10, 'b70 - plan1': 5, 'c30 - plan1': 5},
{date: '9 - 2021', 'a20 - plan1': 5, 'b70 - plan1': 5, 'c30 - plan1': 5}
];
And I would like to group by the date
and sum the fields that are equal resulting in the following array:
const data = [
{date: '8 - 2021', 'a20 - plan1': 30, 'b70 - plan1': 15, 'c30 - plan1': 10},
{date: '9 - 2021', 'a20 - plan1': 65, 'b70 - plan1': 75, 'c30 - plan1': 25},
];
I would be glad if I could get any help, thanks in advance!
Upvotes: 1
Views: 1028
Reputation: 56
Another solution can be separate into a hash map and then re-create a new array from it.
const data = [
{date: '8 - 2021', 'a20 - plan1': 20, 'b70 - plan1': 10, 'c30 - plan1': 5},
{date: '9 - 2021', 'a20 - plan1': 60, 'b70 - plan1': 70, 'c30 - plan1': 20},
{date: '8 - 2021', 'a20 - plan1': 10, 'b70 - plan1': 5, 'c30 - plan1': 5},
{date: '9 - 2021', 'a20 - plan1': 5, 'b70 - plan1': 5, 'c30 - plan1': 5}
];
const groupDataByDate = (array) => {
const groups = {};
// we create a hash map with the sum of each element grouping by date
array.forEach(item => {
const { date, ...props } = item;
if (!groups[date]) groups[date] = {};
Object.keys(props).forEach(key => {
if (!groups[date][key]) groups[date][key] = 0;
groups[date][key] += item[key];
})
});
// if we want to preserve as an array, we need to transform this hash map into the same array
return Object.keys(groups).map(key => {
return {
date: key,
...groups[key], // this attribute contains the sums for each group
};
});
// otherwise you can just return the groups
// uncomment next line if the object helps you
// return groups;
}
console.log(groupDataByDate(data));
/*
// expected result
const data = [
{date: '8 - 2021', 'a20 - plan1': 30, 'b70 - plan1': 15, 'c30 - plan1': 10},
{date: '9 - 2021', 'a20 - plan1': 65, 'b70 - plan1': 75, 'c30 - plan1': 25},
];
*/
Upvotes: 0
Reputation: 2270
using simple reduce can give you the solution. first, use a dictionary to insert the first set of unique 'date' as key and object as value, and when you find another matching date key, simply add current with the previous value saved in the dictionary.
const data = [
{date: '8 - 2021', 'a20 - plan1': 20, 'b70 - plan1': 10, 'c30 - plan1': 5},
{date: '9 - 2021', 'a20 - plan1': 60, 'b70 - plan1': 70, 'c30 - plan1': 20},
{date: '8 - 2021', 'a20 - plan1': 10, 'b70 - plan1': 5, 'c30 - plan1': 5},
{date: '9 - 2021', 'a20 - plan1': 5, 'b70 - plan1': 5, 'c30 - plan1': 5}
];
let dictionary = data.reduce((dic, value)=> {
if(!dic[value.date])
{dic[value.date] = value; } else {
let old = dic[value.date];
Object.keys(old).forEach((key)=> { if(key != 'date') { old[key] += value[key] } } )
} return dic } ,{});
let result = Object.values(dictionary);
console.log(result);
Upvotes: 1