Does Underscore.js have a findLast()
method or equivalent?
What is the best way to do .find()
but return the last item that matches in Collection?
Adding Underscore to a Node. Once added, underscore can be referred in any of the Node. js modules using the CommonJS syntax: var _ = require('underscore'); Now we can use the object underscore (_) to operate on objects, arrays and functions.
The _.each function accepts an array or an object, an iteratee function and an optional context object, the iteratee function is invoked once and in order for each array item The iteratee function provides 3 arguments item - The current iterated object (or value if an object was passed) i - The index of the iterated ...
chain() function is an inbuilt function in Underscore. js library of JavaScript which is used to find a wrapped object. Moreover, invoking the methods on this object will continue to return the wrapped objects until the value is invoked.
Reverse the list and then use find
:
_.find(list.slice().reverse(), iterator);
Read MDN for the documentation on reverse
.
Unfortunately a collection in underscore may be either an array or an object. If your collection is an array then you're in luck. You can use reverse
. However if it's an object then you'll need to do this instead:
_.find(Object.keys(list).reverse(), function (key) {
return iterator(list[key], key, list);
});
You could write a findLast
function for yourself:
_.mixin({
findLast: function (list, iterator, context) {
if (list instanceof Array)
return _.find(list.slice().reverse(), iterator, context);
else return _.find(Object.keys(list).reverse(), function (key) {
return iterator.call(context, list[key], key, list);
});
}
});
Now you can use findLast
like any other underscore method.
Underscore 1.8.0 introduced a method findLastIndex which can be used to accomplish this.
var numbers = [1, 2, 3, 4];
var index = _.findLastIndex(numbers, isOddNumber);
if (index > 0) { console.log(numbers[index]); }
// returns 3
Using reverse
, as suggested by @AaditMShah, is the easiest solution, but be aware that it manipulates the array in place. If you need to preserve the order of elements, you'd have to call reverse
a second time, after you are done.
If you don't want to use reverse
, you can
_.findLast
findLast
and forEachRight
and make your own findLast.This is what it looks like if you only deal with arrays and don't care about objects:
function findLast (array, callback, thisArg) {
var index = array.length,
last;
callback = callback && typeof thisArg == 'undefined' ? callback : _.bind(callback, thisArg);
while (index--) {
if (callback(array[index], index, array) == true) {
last = array[index];
break;
}
}
return last;
}
(It works, but I haven't tested it properly. So to anyone reading this, please run a few tests first and don't just copy the code.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With