dzm
dzm

Reputation: 23544

Unique object keys but add the other

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

Answers (2)

code-jaff
code-jaff

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;
}, []);

DEMO

Upvotes: 0

Reactgular
Reactgular

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

Related Questions