Reputation: 883
I have some data like this (simplified):
sales: [
{
'quantity': 20,
'amount': 40,
'product': {
'id': 1
'category': 'Chemical',
'subcategory': 'Herbicide'
}
},
{
'quantity': 10,
'amount': 70,
'product': {
'id': 1
'category': 'Chemical',
'subcategory': 'Herbicide'
}
},
{
'quantity': 30,
'amount': 60,
'product': {
'id': 2
'category': 'Seed',
'subcategory': 'Corn'
}
}
]
I want to group my data by the product.id
and sum the quantity
and amount
and keep the same category
and subcategory
(which would be the same for all same product id's)
So basically I want my data to look like this:
filteredSum: [
{
'quantity': 30,
'amount': 110,
'product': {
'category': 'Chemical',
'subcategory': 'Herbicide'
}
},
{
'quantity': 30,
'amount': 60,
'product': {
'category': 'Seed',
'subcategory': 'Corn'
}
}
]
I'm using Lodash and this is what I came up with but something tells me there is a more succinct way of doing this?
filteredSum: function () {
return _(this.sales).groupBy('product.id').map(function (sales) {
return {
'quantity': _.sumBy(sales, function(sale) { return Number(sale.quantity); }).toFixed(2),
'amount': _.sumBy(sales, function(sale) { return Number(sale.amount); }),
'product': {
'category': _.head(sales).product.category,
'subcategory': _.head(sales).product.subcategory
}
}
}).value();
}
Surely there is a better way?
Upvotes: 0
Views: 59
Reputation: 7605
The easiest way is to have an Object with the productId
as principal key. Then simply use a reduce
to iterate over your array. If the productId
of the current product already exists, simply sum its value to the previous one, otherwise add it to the object.
const data = [
{
'quantity': 20,
'amount': 40,
'product': {
'id': 1,
'category': 'Chemical',
'subcategory': 'Herbicide'
}
},
{
'quantity': 10,
'amount': 70,
'product': {
'id': 1,
'category': 'Chemical',
'subcategory': 'Herbicide'
}
},
{
'quantity': 30,
'amount': 60,
'product': {
'id': 2,
'category': 'Seed',
'subcategory': 'Corn'
}
}
];
const result = data.reduce((acc, curr) => {
if (acc[curr.product.id]) {
acc[curr.product.id].quantity += curr.quantity;
acc[curr.product.id].amount += curr.amount;
} else {
acc[curr.product.id] = curr;
}
return acc;
}, {});
const formatedResult = Object.keys(result).map(entry => {
return result[entry];
});
console.log(formatedResult);
Upvotes: 3