Using Underscore.js, I can write the following which returns 42
:
_([42, 43]).chain()
.first()
.value()
I have custom f
Using compose
is another way dealing with the situation, but I think adding a function such as take
as I suggested earlier is a better solution. Still, here is how the code would look like with compose
:
function double(value) { return value * 2; };
_.compose(
double,
_.first,
_.bind(_.identity, _, [42, 43])
)();
The initial value needs to be provided through a function which returns that value (here done by currying identity
), and the functions need to be listed in an other which is the reverse of what you have with a chain, which appears as pretty unnatural to me.
Not finding a tap
that returns the value returns by the function is runs, I define one which I can take
and add to _
:
_.mixin({take: function(obj, interceptor) {
return interceptor(obj);
}});
Then assuming I have:
function double(value) { return value * 2; };
I can write:
_([42, 43]).chain()
.first() // 42
.take(double) // Applies double to 42
.value() // 84
You can look at take
as map
on objects, instead of lists. Want to experiment with this? See this example on jsFiddle.
Alright, I'm fresh off of reading the underscore annotated source code for the first time. But I think you can do something like this:
function double(value) { return value * 2; };
var obj = _([42, 43]).addToWrapper({double:double});
obj.chain()
.first()
.double()
.value();
The syntax/details might not be right, but the core point is this: when you call _([42,43])
, you're calling underscore as a function. When you do so, it instantiates a new object and then mixes into that object most of the underscore functions. Then, it returns that object to you. You can then add your own functions to that object, and none of this pollutes the "_" namespace itself.
That's what the underscore.js code looked like to me. If I'm wrong, I'd like to find out and hopefully someone will explain why.
EDIT: I've actually been using underscore.js heavily for about a month now, and I have gotten pretty familiar with it. I now know it behaves like I said here. When you call _ as a Constructor function, you get back your own "namespace" (just an object), and you can add things to it with addToWrapper() that show up in your namespace but not in the "global" "_" namespace. So the feature the OP wanted is already built in. (And I have been really impressed with underscore, btw, it is very very nicely done).
Does map
work for this?
_([42, 43]).chain()
.first()
.map(double)
.value()
edit
from the documentation, it looks like map
would only work if you place it before the call to first
:
_([42, 43]).chain()
.map(double)
.first()
.value()
Many ways to easily achieve this, here is one such solution:
_.chain([42,43])
.first(1)
.map(double)
.first()
.value();
// 84
However, I would recommend using Ramda then with auto-curry and pipe / compose these kinds of tasks are trivial:
R.pipe(R.head, R.multiply(2))([42, 43]); // 84
equivalent to:
R.compose(R.multiply(2), R.head)([42, 43]); // 84
If you wanted to extend the solution to take say the first 2 items, instead of a single value, as requested by the OP, then:
R.pipe(R.take(2), R.map(R.multiply(2)))([42, 43]) // [84, 86]
However, in Ramda R.compose is preferred. Either way, for trivial tasks like this, it does tend to be more convenient and easy to use.
So you have a custom function:
function double(value) { return value * 2; }
You can use mixin to extend Underscore with it:
_.mixin({ double:double });
Now you can call your function from the Underscore object _
:
_.double(42); // 84
and from the wrapped object returned from chain
:
_([42, 43]).chain()
.first()
.double() // double made it onto the wrapped object too
.value(); // 84