I made a small plnkr here to show what I am trying to achieve. I have a big dataset, where I like to sum the individual type to get a total.
I could think of iterating and adding the results to an object hash, but wonder more elegant way to solve it with underscore. I am using underscore.js, but never tried map reduce or other functional paradigm. Please update the plnkr to learn how to do this.
http://plnkr.co/edit/B5HGxhwvWsfvOR97z7TL?p=preview
var data = [ {'type': "A", 'val':2},
{'type': "B", 'val':3},
{'type': "A", 'val':1},
{'type': "C", 'val':5} ];
_.each(data, function (elm, index) {
console.log(elm);
});
/*
Desired output
out = [ {'type': "A", 'total':3},
{'type': "B", 'total':3},
{'type': "C", 'total':5} ];
*/
var data = [ { type: "A", val: 2 },
{ type: "B", val: 3 },
{ type: "A", val: 1 },
{ type: "C", val: 5 } ];
var groups = _(data).groupBy('type');
var out = _(groups).map(function(g, key) {
return { type: key,
val: _(g).reduce(function(m,x) { return m + x.val; }, 0) };
});
DEMO
Pretty much the same answer as @GregL, just with a bit more underscore:
summed_by_type = _(data).reduce(function(mem, d) {
mem[d.type] = (mem[d.type] || 0) + d.val
return mem
}, {})
pairs = _(summed_by_type).map(function(v,k) { return {type: k, total: v} })
The following will work, but I assume it is similar to what you had in mind. The advantage is that by using an object hash to store the totals, you are indexing on the type which means you don't have to iterate through the hash each time trying to find the object with the right type. Then you iterate through it once at the end to build up the final output array.
Plunkr is here.
Code is as follows:
var data = [ {'type': "A", 'val':2},
{'type': "B", 'val':3},
{'type': "A", 'val':1},
{'type': "C", 'val':5} ];
var totalPerType = {};
for (var i = 0, len = data.length; i < len; ++i) {
totalPerType[data[i].type] = totalPerType[data[i].type] || 0;
totalPerType[data[i].type] += data[i].val;
}
var out = _.map(totalPerType, function(sum, type) {
return { 'type': type, 'total': sum };
});
console.log('out = ', out);
EDIT: I have created a new plunkr that generates how fast this is even for a 1 million item array (with 6 possible types) here. As you can see from the console output, at least in Chrome Canary, it runs in about 1/3 second.
I have also done a jsPerf test for how much faster it is to use the intermediate hash, and it works out about 50% faster.