2011-04-29 9 views
6
a, b, c = 0, 1, 2 
[a, b, c].find(&:zero?) # => 0 

¿Hay algún método que encuentre el primer elemento para el cual el bloque devuelve falso?¿Hay algún método en Ruby que haga lo contrario de encontrar?

[a, b, c].the_method(&:zero?) # => 1 

En otras palabras, se comportaría de la misma manera que:

[a, b, c].reject(&:zero?).first 
+0

'reject (...). First' parece lo que buscas, ¿qué pasa con eso? –

+3

¿qué hay de usar _Proc_? '[a, b, c] .find {| i | i! = 0} ' – konus

+2

@Joe el problema es que recorre toda la colección y crea una matriz completa de todos los valores coincidentes, y luego los descarta. La belleza de 'encontrar' es que deja de iterar tan pronto como encuentra el primer valor coincidente. – Phrogz

Respuesta

9

Hay is not, pero se podría crear una tampoco la forma limpia-ish:

a = [0,2,1,0,3] 

module Enumerable 
    def first_not(&block) 
    find{ |x| !block[x] } 
    end 
end 

p a.first_not(&:zero?) 
#=> 2 

.. .o la terriblemente divertida manera-Hack:

class Proc 
    def ! 
    proc{ |o,*a| !self[o,*a] } 
    end 
end 

p a.find(&!(:zero?.to_proc)) 
#=> 2 

... o la manera concisa, pero-terriblemente peligroso:

class Symbol 
    def ! 
    proc{ |o,*a| !o.send(self,*a) } 
    end 
end 

p a.find(&!:zero?) 
#=> 2 

Pero me defiendo simplemente omitiendo el uso complicado Symbol#to_proc y diciendo lo que quiere:

p a.find{ |i| !i.zero? } 
#=> 2 
+0

¡Hack formas de ganar! =) – Aleksey

2

Por lo que yo puedo decir que no hay un método estándar para hacer esto (dado que find_all y rechazar referencia entre sí , pero find no hace referencia a nada). Si lo necesita con frecuencia (especialmente si el rechazo es demasiado lento) usted puede escribir su propia

module Enumerable 

    def first_reject(&block) 
    find {|a| not (block.call(a)) } 
    end 

end 
+0

Sí, sin embargo, estoy de acuerdo con Phrogz en que simplemente escribir la función es generalmente el mejor . –

2

Si está utilizando Rubí 2.0, que puede ser capaz de hacer lazy.reject(&:zero?).first sin la penalización en el rendimiento de pasar por la matriz completa

Cuestiones relacionadas