Just so you know, you can reduce this: return (typeof (o) !== 'undefined' && o !== null); down to this return o != null;. They are exactly equivalent.
– cliffs of insanityMay 5 '12 at 0:08

1

Good to know. But you know, I mistrust the coercing operators like != or ==. I wouldn't even be able to easily test it, as I'd need to check somehow that there is no other value that is coerced to null in that fashion... :) So how lucky I am to have a library that allowed me to remove that function altogether... :)
– Jakub P.May 5 '12 at 1:37

I'd honestly have to say this a fairly elegant solution. The closest thing I can find is Array.prototype.some which tries to find if some element satisfies a given condition you pass to it in the form of a function. Unfortunately, this returns a boolean instead of the index or the element. I would recommend your solution over using a library since libraries tend to be much larger and contain things you won't use and I prefer keeping things light (since you might only use the one function out of the suite it provides).
– Graham RobertsonMar 12 '13 at 0:53

11 Answers
11

since there are so many functional-style array methods in ECMAScript, perhaps there's something out there already like this?

You can use the some Array method to iterate the array until a condition is met (and then stop). Unfortunately it will only return whether the condition was met once, not by which element (or at what index) it was met. So we have to amend it a little:

Can't say I entirely understand all the dislike directed at filter(). It may be slower, but in reality; most cases where this is probably used, it is a small list to begin with, and the majority of JavaScript applications are not complicated enough to really worry about efficiency at this level. [].filter(test).pop() or [].filter(test)[0] are simple, native and readable. Of-course I am talking about businessy apps or websites not intensive apps such as games.
– Josh McFeb 11 '14 at 4:04

11

Does filter solutions traverse all the array/collections? If so, filtering is very inefficient, because it runs over all the array even if the found value is the first one in the collection. some() on the other hand, returns immediately, which is much faster in almost all cases than filtering solutions.
– AlikElzin-kilakaJul 15 '15 at 6:13

@JoshMc sure, but it makes sense not to be gratuitously inefficient when posting a solution to a simple problem somewhere like Stack Overflow. Lots of people will copy and paste the code from here into a utility function, and some of them will, at some point, end up using that utility function in a context where performance matters without thinking about the implementation. If you've given them something that has an efficient implementation to begin with, you've either solved a performance problem they'd otherwise not have, or saved them a bunch of dev time diagnosing it.
– Mark AmerySep 25 '15 at 9:29

If you want to use this right now but need support for IE or other unsupporting browsers, you can use a shim. I recommend the es6-shim. MDN also offers a shim if for some reason you don't want to put the whole es6-shim into your project. For maximum compatibility you want the es6-shim, because unlike the MDN version it detects buggy native implementations of find and overwrites them (see the comment that begins "Work around bugs in Array#find and Array#findIndex" and the lines immediately following it).

find is better than filter since find stops immediately when it finds an element matched the condition, while filter loops through all the elements to give all matched elements.
– Anh TranNov 12 '18 at 8:52

It should be clear by now that JavaScript offers no such solution natively; here are the closest two derivatives, the most useful first:

Array.prototype.some(fn) offers the desired behaviour of stopping when a condition is met, but returns only whether an element is present; it's not hard to apply some trickery, such as the solution offered by Bergi's answer.

Array.prototype.filter(fn)[0] makes for a great one-liner but is the least efficient, because you throw away N - 1 elements just to get what you need.

Traditional search methods in JavaScript are characterized by returning the index of the found element instead of the element itself or -1. This avoids having to choose a return value from the domain of all possible types; an index can only be a number and negative values are invalid.

This doesn't satisfy the output of what the asker requires (needs the element at some index, not a boolean).
– Graham RobertsonMar 12 '13 at 0:48

@GrahamRobertson $.inArray doesn't return a boolean, it (surprisingly!) returns the index of the first matching element. It still doesn't do what the OP asked for, though.
– Mark AmeryAug 6 '15 at 12:05