2010-09-07 123 views
5

我有一个红宝石散列这样
h = {"a" => "1", "b" => "", "c" => "2"}
现在我有一个评估该哈希,如果找到一个空值一键返回true红宝石功能。我有以下函数始终返回true,即使在哈希的所有键都没有空搜索红宝石哈希值为空

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

我在做什么错在这里?请帮助

感谢,ABHI

+2

这工作对我很好。什么是你看到这个问题的散列的例子(因为你的'h'确实有一个空值) – DanSingerman 2010-09-07 11:25:57

回答

8

我希望你”

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

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

或者准备在这里学习一些红宝石魔法。我不会像你那样在全球范围内定义这样的功能。如果它是一个散列的操作,比它应该是在哈希类的实例方法,你可以做这样的:

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

reject会返回一个新的哈希值与所有的空字符串,而且比这将是检查这个新散列有多大。

一个可能更有效的方式(它不应该遍历整个数组):

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

但是,这仍然会遍历整个哈希,如果没有空值

我已经改变empty?!nil? || length >0,因为我不知道你的empty方法是如何工作的。

+1

不像你那样有效1)遍历整个散列,2)不必要地创建另一个结构。 – 2010-09-07 14:10:19

+0

你说得对,如果更新我的答案。 'include?'不应该遍历整个哈希,如果它发现nil的一个发生。但是如果你几乎总是有没有空值的散列,那么它根本就不重要,因为要返回'false',函数必须总是遍历整个散列。 – jigfox 2010-09-07 14:17:49

+0

当然,任何解决方案都应该在没有空白时遍历整个散列。 – 2010-09-07 14:44:32

17

试试这个:如果您使用的是旧1.8.x的红宝石

+4

你可以做'hsh.each_value.any? &:empty?'在ruby> = 1.8.7中避免将其转换为数组。但是这可能只对大型哈希值很重要。 – 2010-09-07 11:50:09

+0

我同意你的意见,使用枚举器更好。 – Nakilon 2010-09-07 12:08:35

+0

警告:这将在响应'empty?'方法的哈希值上触发。例如。 'hash_has_blank({a:[]})== true'这可能不是预期的行为。 @斯坦拉格的建议通常可能更合适。 – Automatico 2015-11-17 20:14:37

4

如果你只是要检查是否有任何价值的是一个空字符串,你可以做

h.has_value?('') 

,但你的功能似乎很好地工作。

4

我会考虑重构你的模型域。显然,哈希表示一些有形的东西。为什么不把它作为一个对象?如果该项目可以完全由散列表示,那么您可能希望子类化哈希。如果它更复杂,散列可以是一个属性。

其次,检查空白的原因可以命名为更好地反映您的域名。你没有告诉我们“为什么”,但是让我们假设你的物品只有在没有任何空白值的情况下才有效。

class MyItem < Hash 

    def valid? 
    !invalid? 
    end 

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

问题是,如果您可以建立一个在您的域中有意义的词汇表,那么您的代码将变得更加清晰和易于理解。使用散列只是达到目的的一种手段,您最好使用更具描述性的,特定领域的术语。

使用上面的例子,你能够做到:

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

my_item.valid? #=> false 
+0

这是一个更干净的方式。 jigfox的解决方案对我来说是如此 – eabhvee 2010-09-07 18:31:19

+0

如果这是一次性脚本,那很好。但在代码审查中,我拒绝了一个基本数据结构的猴子补丁,以支持正确的对象建模。 – 2013-04-17 12:43:52