Reputation: 23544
I have a JSON object like this:
[ { browser: 'IE', count: 5 },
{ browser: 'Safari', count: 4 },
{ browser: 'Mobile Safari', count: 4 },
{ browser: 'IE', count: 9 } ]
What I'd like to do is basically a unique value for browser. So in this case, it would be transformed to (the count values were added together):
[ { browser: 'IE', count: 14 },
{ browser: 'Safari', count: 4 },
{ browser: 'Mobile Safari', count: 4 }]
I know I can just loop through and build a new array, but are there any cleaner/newer methods that could work nicely for this?
Upvotes: 1
Views: 42
Reputation: 9330
how about pure JS solution with caching?
var seen = {};
var reduced = data.reduce(function(pre, next) {
if(typeof seen[next.browser] !== 'undefined') {
pre[seen[next.browser]].count += next.count;
return pre;
}
var temp = {
browser: next.browser,
count: next.count
}
var index = pre.push(temp) - 1;
seen[temp.browser] = index;
return pre;
}, []);
Upvotes: 0
Reputation: 54791
I consider libraries like LoDash to be part of the newer methods. Otherwise you would just have to brute force solve this in javascript.
var arr = [ { browser: 'IE', count: 5 },
{ browser: 'Safari', count: 4 },
{ browser: 'Mobile Safari', count: 4 },
{ browser: 'IE', count: 9 } ]
arr = _.map(_.groupBy(arr,'browser'), function(value, key) {
return { browser: key, count: _.sum(value,'count') };
});
alert(JSON.stringify(arr));
http://jsfiddle.net/thinkingmedia/d40Ljjk5/
First group by browser
, and then you can just sum the count values. The down side is that you have to rebuild the object. That's fine if you know what the format is.
The other approach would be to just assume the first object is the right pattern, and update the count value.
Something like this
arr = _.map(_.groupBy(arr,'browser'), function(value, key) {
var x = _.first(value);
x.count = _.sum(value,'count');
return x;
});
http://jsfiddle.net/thinkingmedia/nj0h0bpg/1/
EDIT: Here's a one line way for the above.
return _.merge(_.first(value), {count: _.sum(value,'count')});
Upvotes: 2