我有一个数组,其中包含一些不同的数据(字符串格式),我想计算每个值的频率并将其存储在哈希/字典中,但是尝试这样做会出错。
我想做这样的事情:
words = ["foo", "var", "spam", "egg", "foo", "foo", "egg"]
frequency = {}
words.each{|word| frequency[word] += 1}
并获得以下输出:
puts(frequency) #{"foo" => 3, "var" => 1, "spam" => 1, "egg" => 2}
但是我遇到了以下问题:
prueba.rb:3:in `block in <main>': undefined method `+' for nil:NilClass (NoMethodError)
还有另一种方法可以达到相同的结果吗?
答案 0 :(得分:4)
如果您在哈希中查询不存在的密钥,则会得到nil
,这就是问题所在。如果没有密钥,让我们将0
设置为默认值
frequency = Hash.new(0)
答案 1 :(得分:1)
写时:
words.each{|word| frequency[word] += 1}
等效于:
words.each{|word| frequency[word] = frequency[word] + 1}
但是,frequency
哈希为空,而frequency[word]
返回nil
-本质上,您正在尝试执行nil + 1
,这会导致您得到错误。 / p>
您可以手动初始化哈希的新元素:
words.each{|word| frequency[word] ||= 0; frequency[word] += 1}
或者,正如其他答案已经建议的那样,使用frequency = Hash.new(0)
作为快捷方式。
答案 2 :(得分:1)
words = ["foo", "var", "spam", "egg", "foo", "foo", "egg"]
words.each_with_object(Hash.new(0)) { |w, h| h[w] += 1 }
#=> {"foo"=>3, "var"=>1, "spam"=>1, "egg"=>2}
#each_with_object是枚举器,它通过将每个元素传递给提供的对象(此处为Hash.new(0)
)进行迭代,并在下一次迭代中返回该提供的对象。
Hash.new(0)
创建一个哈希值,其中任何键的默认值为0。
hash = Hash.new(0)
hash['a'] #=> 0
我们使用默认值的此属性,只需将每个单词传递给对象并增加计数器。 :)
代码中的问题:您的情况下没有默认值,因此您需要通过检查哈希中是否存在键来手动执行此操作。
答案 3 :(得分:0)
您可以使用它。通过使用Hash.new(0)
对其进行初始化names = ["foo", "var", "spam", "egg", "foo", "foo", "egg"]
names.inject(Hash.new(0)) { |total, e| total[e] += 1 ;total}
# {"foo"=>3, "var"=>1, "spam"=>1, "egg"=>2}