8

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?

4

3 回答 3

13

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.

于 2013-09-03T22:16:17.480 回答
4

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
于 2015-12-24T16:07:32.090 回答
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

  • use Lodash instead, which provides _.findLast
  • grab the relevant code from Lodash, spread out over 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.)

于 2014-01-07T14:55:33.507 回答