Ruby - 计算字符串中每个单词的重复次数

时间:2015-02-23 19:37:21

标签: ruby string algorithm split hashmap

我试图从 Ruby Monk 网站上解决这个问题,该网站说:

  

尝试实现一个名为occurrences的方法,该方法接受一个字符串   参数并使用inject来构建哈希。这个哈希的关键应该是   是该字符串中的唯一单词。这些键的值应该是   该单词出现在该字符串中的次数。

我试图这样做:

def occurrences(str)
  str.split.inject(Hash.new(0)) { |a, i| a[i] += 1 }
end

但我总是得到这个错误:

TypeError: no implicit conversion of String into Integer

与此同时,这个解决方案完全相同(我认为):

def occurrences(str)
    str.scan(/\w+/).inject(Hash.new(0)) do |build, word| 
    build[word.downcase] +=1
    build
    end
end

1 个答案:

答案 0 :(得分:2)

好的,你的问题是你没有从块中返回正确的对象。 (在您的情况下为Hash

#inject就像这样

[a,b] 
 ^    -> evaluate block 
 |                      |
  -------return-------- V 

在您的解决方案中,这就是正在发生的事情

def occurrences(str)
 str.split.inject(Hash.new(0)) { |a, i| a[i] += 1 }
end
#first pass a = Hash.new(0) and i = word
  #a['word'] = 0 + 1
  #=> 1 
#second pass uses the result from the first as `a` so `a` is now an integer (1). 
#So instead of calling Hash#[] it is actually calling FixNum#[] 
#which requires an integer as this is a BitReference in FixNum.Thus the `TypeError`

简单修复

def occurrences(str)
 str.split.inject(Hash.new(0)) { |a, i| a[i] += 1; a }
end
 #first pass a = Hash.new(0) and i = word
  #a['word'] = 0 + 1; a
  #=> {"word" => 1} 

现在该块返回Hash再次传递给a。如您所见,解决方案在块的末尾返回对象build,因此解决方案可以正常工作。