/ Javascript

Code Teardown #0 - Lodash's Reduce

Today I’ve decided to write what I am terming a test run on a theme of blog posts I’m considering, ‘Code Teardowns’. I recently was introduced to the site iFixit while listening to an episode of the Hanselminutes podcast and was immediately intrigued by their site. After spending a week on the edge of buying a toolkit to attempt a teardown I decided it was probably important that my phone continue to work and abandoned my plan.

However I recently woke with a realization: I can teardown code and when I’m done my family will still be able to call me! So to get me started I’ve decided to teardown a simple function from the popular functional library ‘lodash’ that I am rather fond of, reduce. (A fondness that has no doubt been amplified by my recent time spent building with React/Redux, which is great).

First of all, if you don’t use reduce please start doing so. It is an incredibly practical and fun little function. Second of all, look how beautifully simple it is. Let’s dive in. This implementation is just like JavaScript’s native reduce in that it is built to only work on array’s. Its function is to iterate over that array, perform some method of accumulation on each item and the return the result. The beauty is in the fact that the method of accumulation is a callback which you can define to do whatever you want! You can use reduce to replace map, to map the array to an object, to sum all items, to sum items conditionally, and if you’re feeling very un-functional you can combine some side effect with the accumulation to condense several operations into one function call! (and please don’t consider that an exhaustive list) I told you, it’s beautiful.

How does it do it? Well the function call itself takes the array as the first argument, that iterate you see in the second argument is the method of accumulation I mentioned before, and the accumulator is the optional initial value of accumulation. That last parameter? An optional Boolean flag that tells the function to use the first item of the array as the initial value instead.

Ok, now the stage is set. The function begins by setting a variable for the index of the array, we’ll come back to why it’s -1, and another for the length of the array.

It then checks to see if the ‘initAccum’ flag is set and properly sets the accumulator to the first item in the array if so.

With the accumulator set the function begins a while loop with the next item, either index 0 or 1, which will continue until each item of the array has been visited. Notice the use of the left side ++ operator which will evaluate before the equality is tested, this will be important in a minute. Inside this loop the accumulator is reset to the result of the call to that wonderful accumulation method, called the iteratee, which takes the current accumulator, the current item value, the index and the whole array to perform its desired operations. (Is your imagination just bursting with all the possibilities?) Finally, when the loop exits the last value of the accumulator is returned out of the function.

Alright, so that seems pretty simple right? And it is! But let’s take a look at a few of the finer points that make this a fast implementation of the function. Remember that the index was initially set to -1? Why couldn’t it have just been at 0? And why does the function bother to save the array length to a variable? Couldn’t it just be checked on the array? Well for starters its much more concise this way. Crockford be damned. Learn the language and use it to make beautiful simple code, don’t fear it. But more important in this case is performance. As it turns out while loops are faster than for loops, incrementing (or decrementing) in the condition is faster than at the bottom of the loop and its faster to check a variable than to check the length of the array (even though it’s a static value stored on the object).

A little skeptical? Good! Don’t take these things for granted, check them out at this jsperf test. Sure the difference might be minimal but when your jdalton you minimize your code base and maximize your performance. It’s what you do.