views:

136

answers:

3

Hi,

Am I missing something in the Array documentation? I have an array which contains up to one object satisfying a certain criterion. I'd like to efficiently find that object. The best idea I have from the docs is this:

candidates = my_array.select { |e| e.satisfies_condition? }
found_it = candidates.first if !candidates.empty?

But I am unsatisfied for two reasons: (1) that select made me traverse the whole array, even though we could have bailed after the first hit, and (2) I needed a line of code (with a condition) to flatten the candidates. Both operations are wasteful with foreknowledge that there's 0 or 1 satisfying objects.

What I'd like is something like:

array.find_first(block) -> answers nil or the first object for which the block evaluates to true, ending the traversal at that object.

Must I write this myself? All those other great methods in Array make me think it's there and I'm just not seeing it.

Thanks in advance, Dan

+1  A: 

Either I don't understand your question, or Enumerable#find is the thing you were looking for.

Mladen Jablanović
Nope. I think you understood it. Thanks (and to the others). I didn't see any of the Enumerable methods. That's just what I needed. Sorry to bother.
Dan Halabe
No problem, I also often find annoying that ruby documentation doesn't list methods of all inherited or included classes and modules.
Mladen Jablanović
@Dan: then at least accept the answer (that's the checkmark next to it).
Marc-André Lafortune
A: 

Guess you just missed the find method in the docs:

my_array.find {|e| e.satisfies_condition? }
sepp2k
A: 

Do you need the object itself or do you just need to know if there is an object that satisfies. If the former then yes: use find:

found_object = my_array.find { |e| e.satisfies_condition? }

otherwise you can use any?

found_it = my_array.any?  { |e| e.satisfies_condition? }

The latter will bail with "true" when it finds one that satisfies the condition. The former will do the same, but return the object.

Taryn East