2010-03-04 24 views
97

¿Me falta algo en la documentación de Array? Tengo una matriz que contiene hasta un objeto que cumple un determinado criterio. Me gustaría encontrar eficientemente ese objeto. La mejor idea que tengo de la documentación es la siguiente:Ruby Array find_first object?

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

Pero estoy satisfecho por dos razones: (1) que seleccionan me hizo recorro todo el conjunto, a pesar de que podríamos haber rescatado después del primer golpe, y (2) Necesitaba una línea de código (con una condición) para aplanar a los candidatos. Ambas operaciones son un desperdicio con el conocimiento previo de que hay 0 o 1 objetos satisfactorios.

Lo que me gustaría es algo así como:

array.find_first(block) -> respuestas nulas o el primer objeto para el cual el bloque se evalúa como verdadera, terminando el recorrido en ese objeto.

¿Debo escribir esto yo mismo? Todos esos otros excelentes métodos en Array me hacen pensar que está ahí y que simplemente no lo estoy viendo.

Gracias de antemano, Dan

Respuesta

143

O yo no entiendo su pregunta, o Enumerable#find es lo que estás buscando.

+1

Nop. Creo que lo has entendido Gracias (y a los demás). No vi ninguno de los métodos Enumerables. Eso es justo lo que necesitaba. Lamento molestarte. –

+25

No hay problema, a menudo me molesta que la documentación de ruby ​​no enumere los métodos de todas las clases y módulos heredados o incluidos. –

+1

más información: '[1,2,3,5,2] .find {| n | pone n; n == 2} 'la iteración se detiene una vez que encuentra el primer elemento con el que coincide. – rajuGT

11

supongo que acabas de perder el método de búsqueda en la documentación:

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

O si te gusta el código de golf, 'my_array.find (&: satisfies_condition?)' –

8

¿Necesita el objeto mismo o hacer lo que necesita saber si hay es un objeto que satisface. En el primer caso, entonces sí: el uso hallazgo:

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

de lo contrario se puede utilizar any?

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

Este último será rescatar la "verdadera" cuando se encuentra uno que satisface la condición. Lo primero hará lo mismo, pero devolverá el objeto.

65

uso conjunto detect método si desea volver primer valor, donde retorna verdadero

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

OR 

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

bloque Si desea devolver todos los valores en bloque proporciona cierto entonces utilizar select

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

'.detect' es exactamente lo que necesito. ¿Pero cuál es la diferencia con '.find' entonces? –

+10

@AugustinRiedinger no hay diferencia, ambos son lo mismo 'detect' es solo un alias de 'find' http://ruby-doc.org/core-2.1.2/Enumerable.html#method-i-find –