_(1) .range(21) .filter((x) => x % 2 > 0) .map((x) => x % 5 === 0 ? 2*x : x) .sum()
Here's another way to do it:
R.compose( R.sum, R.map((x) => x % 5 === 0 ? 2*x : x), R.filter((x) => x % 2 > 0)) (R.range(1, 21))
R is the Ramda library.
So what does
compose do? If
h are functions,
R.compose(f, g, h) returns a function equivalent to
In our case
g is a curried map (meaning that only the first argument of
R.map is given to it so we still need to provide it an array to map over). And
h is a similarly curried filter. Finally, on the last line above we call the function that
compose returns, giving it the same range as before as a parameter.
One of the big advantages I see with
compose vs chaining is that now we're no longer limited to just the functions defined in the library. I can put any function I want in compose, even ones I define.
Plus, as we've already seen with
R.filter, all Ramda functions are curried, which (I'm finding) really hooks up well with function composition.
Here's something else that's pretty cool. If I define a function using
var add3 = R.curry((a, b, c) => a + b + c)
All of the following are equivalent:
add3(1, 2, 3) add3(1)(2, 3) add3(1, 2)(3) add3(1)(2)(3)
Also, you can do this:
var add_to_5 = add3(1, R.__, 4) console.log(add_to_5(2))
Actually, wait... lodash can do this too. :)
Ok, but that's still pretty cool.
curry is a much better function than
partial in my opinion.
Ramda's auto-currying plus
compose is pretty rad. I think I'm probably gonna switch.