【问题标题】:Ruby Hash initialization (default value nil)Ruby Hash 初始化(默认值 nil)
【发布时间】:2013-11-06 03:39:15
【问题描述】:

我一直在阅读 Ruby 文档,并查看有关该问题的其他一些帖子,但我仍然对此感到疑惑:

#counts each number in an array once
array = [1,1,2,5,3,2,5,3,3,3]
numbers = {}
array.each { |num| numbers[num] += 1 }

=> in `block in mode': undefined method `+' for nil:NilClass (NoMethodError)

Hash documentation 中,Hash 的默认值为nil,这就是我假设出现此错误的原因。有没有更好的方法将每个键/(值 += 1)插入数字数组?

【问题讨论】:

  • 假设你在num不是哈希键时执行numbers = Hash.new(0)然后numbers[num] += 1。由于您在创建哈希时给出了默认值0,当Ruby 发现num 不是哈希键时,它会创建一个新的哈希元素h[num] = 0。然后它执行h[num] += 1 # => 1 并且 Bob 是你的叔叔。
  • 谢谢,这更有意义。
  • 如果您想知道,当new 被赋予默认参数时,除非执行分配,否则Ruby 不会创建哈希元素。例如,如果h = Hash.new(0)h[6] 将在 if 语句 if h[6] == 0 中等于 nil,导致条件为 false,并且不会创建 key = 6 的哈希元素(否则会导致如果条件被评估为true)。

标签: ruby hash


【解决方案1】:

尝试将 default 值传递给您的新哈希

numbers = Hash.new(0)

【讨论】:

    【解决方案2】:

    你也可以明确地这样做:

    array.each { |num| numbers[num] = (numbers[num] || 0) + 1 }
    

    【讨论】:

      【解决方案3】:

      injectHash.new(0) 的变体

        numbers = [1,1,2,5,3,2,5,3,3,3].inject(Hash.new(0)){|numbers, number| numbers[number] +=1; numbers}
      

      【讨论】:

        【解决方案4】:

        除了使用哈希默认值之外,您还可以尝试使用group_by

        array = [1,1,2,5,3,2,5,3,3,3]
        numbers = Hash[*array.group_by { |i| i }.flat_map { |k, v| [k , v.size] }]
        

        如果你尝试一下,可能会有更好的方法。

        【讨论】:

          猜你喜欢
          • 2015-11-30
          • 1970-01-01
          • 2014-12-29
          • 2020-02-08
          • 2015-02-25
          • 1970-01-01
          • 2013-01-17
          • 2017-11-22
          相关资源
          最近更新 更多