2012-08-16 22 views

Respuesta

8

Aconsejaría extiende Hash con un nuevo método en lugar de sustituir has_key?.

class Hash 
    def has_rkey?(search) 
    search = Regexp.new(search.to_s) unless search.is_a?(Regexp) 
    !!keys.detect{ |key| key =~ search } 
    end 
end 

Esto funcionará con cadenas, símbolos o una expresión regular como argumentos.

irb> h = {:test => 1} 
 => {:test=>1}   
irb> h.has_rkey?(:te) 
=> true 
irb> h.has_rkey?("te") 
=> true 
irb> h.has_rkey?(/te/) 
=> true 
irb> h.has_rkey?("foo") 
=> false 
irb> h.has_rkey?(:foo) 
=> false 
irb> h.has_rkey?(/foo/) 
=> false 
+2

Tenga en cuenta que esto cambia la complejidad del tiempo de búsqueda de la estructura de datos hash de O (1) a O (n) ... que dependiendo del uso previsto puede obviar por completo el beneficio de usar un hash. – the911s

+0

Pensamiento de seguimiento: si tiene que hacer esto para un conjunto grande de datos, debería considerar crear algún tipo de índice. Por ejemplo, en algunas bases de datos, se puede crear un índice en una expresión regular http://dba.stackexchange.com/questions/10694/pattern-matching-with-like-similar-to-or-regular-expressions-in-postgresql – the911s

2

No estoy al tanto de una respuesta absoluta para esta pregunta, pero si tuviera que escribir un método hacky para esto, yo haría esto

!!hash.keys.detect{ |k| k.to_s =~ /Your_Regex_here/ } 

Esto devolverá true cuando cualquier tecla coincide con la expresión regular y false en caso contrario.

+1

solo un consejo, 'detectar' se detendrá tan pronto como encuentre un elemento donde el predicado devuelve verdadero. Esto evitaría tener que iterar sobre toda la colección y luego verificar y ordenar con 'empty?' – Kyle

+0

Actualicé mi respuesta también. –

4

Si sólo está interesado en una respuesta sí/no, entonces any? podría ser una buena opción:

hash.keys.any? { |key| key.to_s.match(regexp)} 

donde regexp es una expresión regular.

+1

'any' es superior a' detectar', ya que devuelve un booleano como se desee. Tenga en cuenta que tiene un error tipográfico: clave => teclas –

+0

Gracias, el error está corregido, y sí, la razón principal de esto - tarde - respuesta fue proporcionar una forma en la que no tiene que '' 'obtener un' booleano'. – qqbenq

+0

'hash.keys.find {...}' devolverá el nombre de la clave, si es necesario –

3

Creo que usar any? es una buena solución según lo declarado por qqbenq, pero preferiría usarlo con grep, ya que es más sucinto. hash.keys.grep(/regexp/).any?