2010-03-04 12 views
97

Fehle ich etwas in der Array-Dokumentation? Ich habe ein Array, das bis zu einem Objekt enthält, das ein bestimmtes Kriterium erfüllt. Ich möchte dieses Objekt effizient finden. Die beste Idee, die ich aus der Dokumentation habe, ist dies:Ruby Array find_first object?

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

Aber ich bin aus zwei Gründen unzufrieden: (1), die ich die ganze Reihe durchqueren wählen gemacht, obwohl wir nach dem ersten Treffer der Klemme geholfen haben könnten, und (2) Ich brauchte eine Codezeile (mit einer Bedingung), um die Kandidaten zu verflachen. Beide Operationen sind verschwenderisch mit dem Vorwissen, dass es 0 oder 1 befriedigende Objekte gibt.

Was würde Ich mag es, so etwas wie:

array.find_first(block) -> Antworten Null oder das erste Objekt, für das der Block true ergibt, an diesem Objekt die Traversal endet.

Muss ich das selbst schreiben? All diese anderen großartigen Methoden in Array lassen mich denken, dass es da ist und ich sehe es einfach nicht.

Vielen Dank im Voraus, Dan

Antwort

143

Entweder ich Ihre Frage nicht verstehen, oder Enumerable#find ist das, was Sie suchen.

+1

Nope zurückkehren wollte. Ich denke du hast es verstanden. Danke (und an die anderen). Ich habe keine der Enumerable-Methoden gesehen. Genau das habe ich gebraucht. Entschuldige die Störung. –

+25

Kein Problem, finde ich auch oft ärgerlich, dass die Ruby-Dokumentation keine Methoden aller vererbten oder enthaltenen Klassen und Module auflistet. –

+1

mehr Infos: '[1,2,3,5,2] .find {| n | setzt n; n == 2} 'Iteration stoppt, sobald das erste übereinstimmende Element gefunden wird. – rajuGT

11

Raten Sie nur die Methode find in der Dokumentation verpasst:

my_array.find {|e| e.satisfies_condition? } 
+4

Oder wenn Sie Code Golfen mögen, 'my_array.find (&: satisferences_condition?)' –

8

Haben Sie das Objekt selbst benötigen oder brauchen Sie nur zu wissen, ob es ein Objekt, das erfüllt ist. Wenn die ehemalige dann ja: Verwendung finden:

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

sonst Sie any?

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

Letzteres wird bürgen mit „true“ verwenden können, wenn er einen findet, der die Bedingung erfüllt. Ersteres wird dasselbe tun, aber das Objekt zurückgeben.

65

Verwendung Array detect Methode, wenn Sie erste Wert in dem Block true zurück

[1,2,3,11,34].detect(&:even?) #=> 2 

OR 

[1,2,3,11,34].detect{|i| i.even?} #=> 2 

Wenn Sie wollten zurückkehren alle Werte in dem Block gibt true zurück, dann verwenden select

[1,2,3,11,34].select(&:even?) #=> [2, 34] 
+4

'.detect' ist genau das, was ich brauche. Aber was ist der Unterschied zu '.find' dann? –

+10

@AugustinRiedinger keinen Unterschied, beide sind same.'detect' ist nur ein Alias ​​für 'find' http://ruby-doc.org/core-2.1.2/Enumerable.html#method-i-find –