Search code examples
javascriptarraysuniqueaverage

Summarize array of objects and calculate average value for each unique object name


I have an array like so:

var array = [
     {
       name: "a",
       value: 1 
     },
     {
       name: "a",
       value: 2 
     },
     {
       name: "a",
       value: 3 
     },
     {
       name: "b",
       value: 0 
     },
     {
       name: "b",
       value: 1 
     }
 ];

And I need an array like this:

var newarray = [
     {
       name: "a",
       value: 2
     },
     {
       name: "b",
       value: 0.5
     }
 ]

Where the new array has each unique name as an object with the average value.

Is there an easy way to accomplish this?


Solution

  • You'll have to loop through the array, computing the sum and counts for each object. Here's a quick implementation:

    function average(arr) {
        var sums = {}, counts = {}, results = [], name;
        for (var i = 0; i < arr.length; i++) {
            name = arr[i].name;
            if (!(name in sums)) {
                sums[name] = 0;
                counts[name] = 0;
            }
            sums[name] += arr[i].value;
            counts[name]++;
        }
    
        for(name in sums) {
            results.push({ name: name, value: sums[name] / counts[name] });
        }
        return results;
    }
    

    Demonstration

    Note, this kind of thing can be made much easier if you use a library like Underscore.js:

    var averages = _.chain(array)
                    .groupBy('name')
                    .map(function(g, k) {
                        return { 
                            name: k, 
                            value: _.chain(g)
                                    .pluck('value')
                                    .reduce(function(x, y) { return x + y })
                                    .value() / g.length
                        };
                    })
                    .value();
    

    Demonstration