As is widely known, JavaScript is a language with good semantics, not-so-good syntax and a terrible standard library. There are a few modules that aim to help with the last part, and lodash is one of them that I happen to use. It is a very nice thing, but is not necessarily easy to learn for newcomers. One of its nice features is so-called “iteratee shorthand”, mentioned many times in the docs. What is that? Well, Lodash has (among many others) the _.iteratee
function. It accepts one argument and returns a function. If the argument is a function, _.iteratee
just returns the same function – nothing interesting (and if given null
, it returns the identity function).
The first interesting thing happens when the argument is a string or an integer. (This also happens with e.g. Booleans, although I’m not sure whether this should be ever used…) The _.iteratee
function then creates a function which, handed an object, returns its property with the given name (or, when handed an array, returns its element with the given index). The string can also be a “path”, e.g. something of the form 'prop1.prop2.prop3'
, and this can be used to create functions which reach deeper in the object structure.
Things get even more interesting when _.iteratee
is given some object obj
. In such a case, it generates a function which returns true
if its sole argument “matches” obj
. (Here, “matches” means “has the same properties with the same values”. Of course, this is not a symmetric relation – {a: 1, b: 2}
matches {a: 1}
, but not the other way round.).
Unfortunately, we can’t use this “matching” technique to reach deeper into the object.
Now it is clear that _.iteratee
can be useful in a lot of places. For instance, if we have an array A
of arrays, and we want to get their first elements, we can say (in pure JS) A.map(a => a[0])
. The direct lodash equivalent is _.map(A, a => a[0])
(not really better than vanilla JS), or – using _.iteratee
– _.map(A, _.iteratee(0))
(which is even worse, since it is too verbose, at least for my taste). And here is the gist: many lodash functions (including _.map
) implicitly wrap the relevant argument in _.iteratee
. Thus, the idiomatic lodash version is actually _.map(a, 0)
, which is (finally) better (that is, shorter) than the vanilla JS solution.