2010-09-07 22 views
5

tengo un hash de rubí como esto
h = {"a" => "1", "b" => "", "c" => "2"}
Ahora tiene una función de rubí que evalúa este hash y devuelve verdadero si encuentra una clave con un valor vacío. Tengo la siguiente función, que siempre devuelve cierto incluso si todas las claves en el hash no están vacíosBuscar ruby ​​hash de valor vacío

def hash_has_blank(hsh) 
    hsh.each do |k,v| 
    if v.empty? 
     return true 
    end 
    end 
    return false 
end 

¿Qué estoy haciendo mal aquí? Por favor, ayuda

Gracias, Abhi

+2

Esto funciona muy bien para mí.¿Cuál es un ejemplo de hash en el que está viendo este problema (como su 'h' tiene un valor en blanco) – DanSingerman

Respuesta

8

Te espero' estoy listo para aprender un poco de magia de rubí aquí. No definiría esa función globalmente como lo hizo. Si se trata de una operación en un hash, de lo que debería ser un método de instancia en la clase Hash puede hacerlo de esta manera:

class Hash 
    def has_blank? 
    self.reject{|k,v| !v.nil? || v.length > 0}.size > 0 
    end 
end 

reject volverá un nuevo hash con todas las cadenas vacías, y de lo que será comprobó qué tan grande es este nuevo hash.

ser un medio más eficiente (que no debe atravesar toda la matriz):

class Hash 
    def has_blank? 
    self.values.any?{|v| v.nil? || v.length == 0} 
    end 
end 

Pero esto todavía va a recorrer todo el hachís, si no hay un valor vacío

He cambiado empty? a !nil? || length >0 porque no sé cómo funciona su método empty.

+1

No es tan eficiente como usted 1) atraviesa todo el hash, y 2) hace otra estructura innecesariamente. –

+0

Tienes razón, si actualizas mi respuesta. 'include?' no debe atravesar el hash completo, si encuentra una ocurrencia de nil. Pero si casi siempre tiene hashs que no tienen valores vacíos, no debería importar nada, porque para devolver 'false', la función SIEMPRE debe recorrer todo el hash. – jigfox

+0

Por supuesto que cualquier solución debe atravesar hash completo cuando no hay espacios en blanco. –

17

Prueba esto:

def hash_has_blank hsh 
    hsh.values.any? &:empty? 
end 

O:

def hash_has_blank hsh 
    hsh.values.any?{|i|i.empty?} 
end 

Si está utilizando un viejo 1.8.x Rubí

+4

Podría hacer 'hsh.each_value.any? &: vacío? 'en ruby> = 1.8.7 para evitar echarlo en una matriz. Pero eso solo podría importar para hash grandes. –

+0

Estoy de acuerdo contigo, usar el enumerador es mejor. – Nakilon

+0

Advertencia: Esto se activará en valores hash que responden al método 'empty?'. P.ej. 'hash_has_blank ({a: []}) == true' que podría no ser el comportamiento esperado. La sugerencia de @ steenslag a menudo puede ser más apropiada. – Automatico

4

Si lo que desea es comprobar si alguno de los valores es una cadena vacía que podría hacer

h.has_value?('') 

pero su función parece funcionar bien.

4

Considero refactorizar el dominio de su modelo. Obviamente, el hash representa algo tangible. ¿Por qué no convertirlo en un objeto? Si el elemento puede estar completamente representado por un hash, es posible que desee crear una subclase Hash. Si es más complicado, el hash puede ser un atributo.

En segundo lugar, se puede nombrar el motivo por el que está marcando espacios en blanco para reflejar mejor su dominio. No nos ha dicho el "por qué", pero supongamos que su artículo solo es válido si no tiene ningún valor en blanco.

class MyItem < Hash 

    def valid? 
    !invalid? 
    end 

    def invalid? 
    values.any?{|i| i.empty?} 
    end 
end 

El punto es, si se puede establecer un vocabulario que tiene sentido en su dominio, su código será más limpio y más comprensible. Usar un Hash es solo un medio para un fin y sería mejor usar términos más descriptivos y específicos del dominio.

Utilizando el ejemplo anterior, usted sería capaz de hacer:

my_item = MyItem["a" => "1", "b" => "", "c" => "2"] 

my_item.valid? #=> false 
+0

Esta es una manera más limpia de hacerlo. La solución de jigfox lo hace por mí – eabhvee

+0

Si esto fue un guion desechable, está bien. Pero en una revisión de código, rechazaría un parche mono de una estructura de datos básica a favor del modelado de objetos adecuado. –