【问题标题】:Ruby - Count each word repetition in a stringRuby - 计算字符串中每个单词的重复次数
【发布时间】:2015-02-23 19:37:20
【问题描述】:

我正在尝试从 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

【问题讨论】:

    标签: ruby string algorithm split hashmap


    【解决方案1】:

    好的,所以您的问题是您没有从块中返回正确的对象。 (在你的情况下是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,因此该解决方案有效。

    【讨论】:

    • 很好的解释。非常感谢您的努力。
    猜你喜欢
    • 1970-01-01
    • 2019-07-31
    • 2016-06-28
    • 2012-10-04
    • 1970-01-01
    • 2014-06-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多