Get first element of a collection that matches iterator function

58,033

Solution 1

You can use find:

Looks through each value in the list, returning the first one that passes a truth test (iterator), or undefined if no value passes the test. The function returns as soon as it finds an acceptable element, and doesn't traverse the entire list.

Using your example:

var g = _.find(arr, function (x) { return x.a > 10 })

See the main page: http://underscorejs.org

Another thing to note (which might be your question) is the chain function to join calls together:

var g = _.chain(arr).filter(function (x) { return x.a > 10 }).first().value()

Notice the calls to filter and `first' which can follow each other without any nesting.

Solution 2

Adding the standard JavaScript Array.prototype.find method, as just the old answers would leave newcomers ill informed:

const array1 = [5, 12, 8, 130, 44];
const found = array1.find(element => element > 10);
console.log(found); 
// expected output: 12

The example is from the above linked MDN page. There's also an Array.prototype.findIndex method that returns the index of where the predicate yielded true, rather than the array element of that index.

These methods are in ES2015 ie. 5 years old and are in pretty much all of the browsers people use, see this caniuse link.

Share:
58,033

Related videos on Youtube

ducin
Author by

ducin

py / js / java enthusiast. Curious of many technologies.

Updated on July 09, 2022

Comments

  • ducin
    ducin almost 2 years

    I would like to achieve something like _.first with _.filter, that is, having a collection of elements, I'd like to get the first one (if exists) that matches a truth test (iterator).

    For example, given an array like the following:

    var arr = [{a: 1}, {a: 5}, {a: 9}, {a: 11}, {a: 15}]
    

    I would like to getthe first (and only first) element that matches my custom function:

    _.filterFirst(arr, function(el) { return el.a > 10; }); // make it
    

    So far:

    _.first(arr) == {a:1}
    _.filter(arr, function(...)) == [{a:11}, {a:15}]
    

    Is there a clean solution to do this which is better than _.first(_.filter(arr, iterator))?

    • Gruff Bunny
      Gruff Bunny over 10 years
      Have a look at the find function underscorejs.org/#find
    • levi
      levi over 10 years
      Why not just _.filter(arr, iterator)[0]
    • ducin
      ducin over 10 years
      @levi because it consumes more CPU than it should.
    • Robert Ravikumar
      Robert Ravikumar almost 6 years
      Why not just _.filter(arr, iterator)[0]
    • ducin
      ducin almost 6 years
      @RobertRavikumar have you ever heard of performance? Or algorithmic complexity? Here you go. BTW that question is 5-years old
  • ducin
    ducin over 10 years
    precisely! _.find is what I need!
  • Andy Mikhaylenko
    Andy Mikhaylenko almost 7 years
    ...or Array.prototype.find(), but it's not supported by IE. One can use a polyfill though. Note that just translating ES2015+ to ES5 would not be enough.