Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Underscore.js findLast() method

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?

like image 465
Quang Van Avatar asked Sep 03 '13 22:09

Quang Van


People also ask

How do you use underscore in JavaScript?

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.

What is _ each in JavaScript?

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 ...

What does _ chain do?

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.


3 Answers

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.

like image 134
Aadit M Shah Avatar answered Oct 02 '22 15:10

Aadit M Shah


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
like image 45
Jarid R. Margolin Avatar answered Oct 02 '22 15:10

Jarid R. Margolin


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.)

like image 39
hashchange Avatar answered Oct 02 '22 15:10

hashchange