You could group it with a hash table and take it as reference for adding the values.
Main structure:
grouped = data.reduce(function (hash) { // closure over hash
return function (r, a) { /* ... */ }; // returns function for callback
}(Object.create(null)), []); // call of IFFE with an empty object
The main idea is to use a variable hash outside of the global context, but usable inside of the callback for Array#reduce.
This works with an IIFE (Immediately Invoked Function Expression), which is a function which is directly after declaration invoked with an empty object.
This creates the variable hash with an empty object and returns the function for the callback.
Inside of the callback:
The callback works with two variables, r and a.
function (r, a) {
// business logic
return r;
}
At start, variable r gets the initialValue, of an empty array []. In this array, the result set is collected and returned for every iteration. This parameter is describes as accumulator.
Parameter a is the current value of the array. This is a single object, like
{
item: 'abc',
category: 'car',
price: 1000
}
and only one object is being processed at the same time.
Basically this solution works with an object and it looks at the end like this
{
car: {
category: "car",
price: 6000
},
bike: {
category: "bike",
price: 1500
},
plane: {
category: "plane",
price: 9000
}
}
where the properties, like car or bike give the reference to the result array without the property car or bike.
At first, a check is made, if the category exists in the hash table. If not, then a new object is created with category and a price with zero, because the price property gets updated for every item within the same category. Then the new object reference gets pushed to the result array.
After the check, the property exist already or is just created, the price property gets an update with the actual value.
At last, the result set is returned for the next update iteration or as final result.
var data = [{ item: 'abc', category: 'car', price: '1000' }, { item: 'abc', category: 'bike', price: '1000' }, { item: 'abc', category: 'car', price: '2000' }, { item: 'abc', category: 'car', price: '3000' }, { item: 'abc', category: 'bike', price: '500' }, { item: 'abc', category: 'plane', price: '9000' }],
grouped = data.reduce(function (hash) {
return function (r, a) {
if (!hash[a.category]) {
hash[a.category] = { category: a.category, price: 0 };
r.push(hash[a.category]);
}
hash[a.category].price += +a.price;
return r;
};
}(Object.create(null)), []);
console.log(grouped);
.as-console-wrapper { max-height: 100% !important; top: 0; }