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

Ruby - Count each word repetition in a string

我正在尝试从 Ruby Monk 网站上解决这个练习,上面写着:

Try implementing a method called occurrences that accepts a string argument and uses inject to build a Hash. The keys of this hash should be unique words from that string. The value of those keys should be the number of times this word appears in that string.

我试过这样做:

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

好的,你的问题是你没有从块中返回正确的对象。 (在你的情况下 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} 

现在块 returns Hash 将再次传递给 a。如您所见,解决方案 returns 块末尾的对象 build 因此解决方案有效。