Javascript Map and Reduce Functions

I was working on a project where I needed to do an aggregate sum of a specific property of an array of objects. Consider the following:

var obj = [
  {
    thread: 'An Essay on Javascript',
    comments: 9
  },
  {
    thread: 'An Essay on HTML',
    comments: 2
  },
  {
    thread: 'An Essay on CSS3',
    comments: 5
  }
];

Let’s say you wanted to figure out the total sum of comments for all threads. You could do:

var total_comments = 0;
for (var i = 0; i < obj.length; i++) {
  total_comments += obj[i].comments;
};

Or, with the ECMA-262 standard in mind:

var total_comments = 0;
obj.forEach(function (o) {
  total_comments += o.comments;
});

Another method, however, is to use the map and reduce functions to accomplish the same thing. In this case, we'll utilize one line of code and leverage method chaining:

var total_comments = obj
  .map(function (o) { return o.comments; })
  .reduce(function (p, c) { return p + c; }, 0);

In the above code, the reduce function requires an array of values to perform the summation. For example:

// Returns 15; note that 0 is the initial value.
[1, 2, 3, 4, 5].reduce(function (previousVal, currentVal) { return previousVal + currentVal; }, 0);

So, based on the variable obj above, how do we get an array of values to feed to the reduce function? The answer is to use the map function:

// Returns [9, 2, 5].
obj.map(function (o) { return o.comments; });

Remember the map function returns an array. In the above example, we're using the map function to "pick" only the comments property to build the array. So, conceptually, this is what's happening:

var total_comments = obj // Remember, obj contains: [{..., comments: 9}, {..., comments:2}, {..., comments:5}]
  .map(function (o) { return o.comments; }) // Map "picks" only the comments property to return [9, 2, 5]
  .reduce(function (p, c) { return p + c; }, 0); // Reduce then sums the [9, 2, 5] array elements

It's important to note, however, that this method is not compatible with IE8 (surprise). As a workaround, you could include map and reduce prototypes provided by the Mozilla Developer Network in your scripts.