In the previous post I showed how good use of Underscore.js‘s
map function can substantially increase the quality of your code. This time I’ll explore some other functional collection favourites:
Reduce that array over a low heat until thick and creamy
Have you ever had to do something like this?
Basically, this is going through some kind of list of values, calculating a new value from each one and accumulating some kind of answer. It’s a common pattern, and there’s an Underscore function for it! This is exactly what
_.reduce was built for:
_.reduce takes a collection of values, a function, and a starting value. In this case, the starting value is 0 because we’re building up a running total of numbers. The function is passed the running total (which starts at 0) and each element of the collection. The return value of the function becomes the next value for the running total.
_.reduce doesn’t just need to be used on numbers:
In this case, I’m reducing an array of animal objects into a single string. Of course there are plenty of ways to do the above, but this shows you the flexibility of
Imagine you have an array of strings, but you want a new array of strings that start with a capital letter. You might do that like this:
Now, you won’t be surprised to learn that there’s an Underscore function for doing just that: introducing
Isn’t that much cleaner? Again, we’re abstracting away the minutiae of selecting elements from a list, and just declaring that we want the elements that start with a capital letter. Simples!
All the single ladies
Sometimes you just want to know a yes or no answer about a collection. For example, are all my ladies single?
Hell yes they are. You can read
_.all as “is this statement true about all the elements in my collection?” In the same way,
_.any can be read as “is this statement true about any of the elements in my collection?”
What about this?
Here’s a useful little tip. When you’re working with nested functions in an object context, you’ll find that
this in the nested function doesn’t refer to the object’s context, but the global context. The standard way to deal with this is a line like
that = this; or
self = this;. There’s a nicer way to do this with Underscore. Nearly all the functions for working on collections take an optional
context argument, which specifies what
this will be inside the function. Here’s an example:
Because we’re passing the value of
_.select, the function passed to
_.select is working with the correct
this.maxAge would be undefined.
you can do:
And, coupled with
.chain() you can do awesome chaining things like this:
Pretty cool. Anyway, use whichever feels right to you. Enjoy!