Friday, November 29, 2013

Two Approaches To Using Lodash Reduce

The Lodash reduce() function is an elegant way to reduce your collections down to a single result. For example, to sum an array of numbers, to apply a more elaborate formula to a specific property on a collection of objects, etc. I've found myself using two different approaches with _.reduce() — both have their upsides.

Here's an example that shows both approaches. I've got a basic array, or, collection, with some basic object data inside. The goal is to compute the average values for each property. So we'll want to reduce the collection down into 4 different sums, one for each property — cpu, mem, disk, and net.

The common form of _.reduce() takes two arguments — collection, and callback. The collection is just an array, while the function is applied to each element of the array, reducing it. For instance, to get the sum of an array of numbers, the function just needs to increment the total argument. But in applications, it's seldom that we find ourselves working with these simple arrays. Rather, we have something more akin to our example data — an array of objects.

So before we can use _.reduce(), a transformation must happen. This is where _.pluck() comes in handy — to create the kind of basic array that _.reduce() works best with. This is exactly what the example uses in the first approach. For each object property, we pluck the values and pass the resulting array. The plus side to this approach is that the accumulate() function is straightforward and is unlikely to change. The down side is that we have to make 4 calls to _.reduce(), not all that efficient.

This is where the second approach comes into play — making only 1 call to _.reduce(). Obviously this is much more efficient, so how does it work? The _.reduce() function takes an optional third argument — accumulator. This defaults to the first element in the collection when not specified, but we can change that. Our second approach passes an object to this function. This object looks a lot like the ones in our sample collection. In fact, that's exactly what it is, with the default values set to 0. The accumulate function in this approach is summing the 4 properties in each iteration instead of performing the single sum over 4 iterations — this is the key. The result is also an object, containing the 4 property totals instead of just a number representing a single sum.