Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Equivalent to LINQ's Enumerable.First(predicate)

In C#, we have Enumerable.First(predicate). Given this JavaScript code:

function process() {
  var firstMatch = ['a', 'b', 'c'].filter(function(e) {
    return applyConditions(e);
  }).shift();

  if(!firstMatch) {
    return;
  }

  // do something else
}

function applyConditions(element) {
  var min = 97;
  var max = 122;

  var random = Math.floor(Math.random() * (max - min + 1) + min);

  return element === String.fromCharCode(random);
}

other than forEach, using loop, using multiple or operators or implicitly calling some(predicate), is there a smarter way of finding the firstMatch? Preferably a JavaScript function (something like filterFirst(pedicate)) which short-circuits on first match resembling C#'s Enumerable.First() implementation?

FWIW, I am targeting node.js / io.js runtimes.

like image 942
vulcan raven Avatar asked Feb 12 '15 11:02

vulcan raven


People also ask

What is the difference between FirstOrDefault and SingleOrDefault?

SingleOrDefault() – Same as Single(), but it can handle the null value. First() - There is at least one result, an exception is thrown if no result is returned. FirstOrDefault() - Same as First(), but not thrown any exception or return null when there is no result.

What is the difference between first and FirstOrDefault?

The major difference between First and FirstOrDefault is that First() will throw an exception if there is no result data for the supplied criteria whereas FirstOrDefault() returns a default value (null) if there is no result data.

What is the default value of FirstOrDefault?

The default value for reference and nullable types is null . The FirstOrDefault method does not provide a way to specify a default value. If you want to specify a default value other than default(TSource) , use the DefaultIfEmpty<TSource>(IEnumerable<TSource>, TSource) method as described in the Example section.

What does FirstOrDefault mean in C#?

More Detail. Use the FirstorDefault() method to return the first element of a sequence or a default value if element isn't there.


3 Answers

No need to reinvent the wheel, the correct way to do it is to use .find:

var firstMatch = ['a', 'b', 'c'].find(applyConditions);

If you're using a browser that does not support .find you can polyfill it

like image 135
Benjamin Gruenbaum Avatar answered Oct 11 '22 06:10

Benjamin Gruenbaum


You could emulate this in the case where you want to return the first truthy value with reduce.

['a', 'b', 'c'].reduce(function(prev, curr) { 
    return prev || predicate(curr) && curr; 
}, false);

edit: made more terse with @BenjaminGruenbaum suggestion

like image 35
xzyfer Avatar answered Oct 11 '22 04:10

xzyfer


LINQ users call first and firstOrDefault a lot with no predicate, which is not possible with find. So,

  first() {
    var firstOrDefault = this.firstOrDefault();
    if(firstOrDefault !== undefined)
      return firstOrDefault;
    else
      throw new Error('No element satisfies the condition in predicate.');
  }

  firstOrDefault() {
    return this.find(o => true);
  }
like image 3
toddmo Avatar answered Oct 11 '22 05:10

toddmo