【问题标题】:How do I increment a value for an uninitialized key in a hash?如何增加哈希中未初始化键的值?
【发布时间】:2014-07-18 11:15:42
【问题描述】:

如果我尝试增加一个在散列中尚不存在的键的值,像这样

h = Hash.new
h[:ferrets] += 1

我收到以下错误:

NoMethodError: undefined method `+' for nil:NilClass

这对我来说很有意义,而且我知道这一定是一个非常简单的问题,但我在 SO 上找不到它。如果我事先不知道我将拥有哪些密钥,我该如何添加和增加这些密钥?

【问题讨论】:

  • 答案给出了处理这种情况的正常方法,但你也应该知道你可以简单地写:if h.has_key?(:ferrets); h[:ferrets] += 1; else h[:ferrets] = 1; endHash#has_key? 方法有,不是一个,不是两个,而是三个别名(即,可以使用任何一个):key?include?member?

标签: ruby hashtable


【解决方案1】:

您可以在构造函数中设置哈希的默认值

h = Hash.new(0)
h[:ferrets] += 1
p h[:ferrets]

请注意,设置默认值有一些陷阱,所以你必须小心使用它。

h = Hash.new([]) # does not work as expected (after `x[:a].push(3)`, `x[:b]` would be `[3]`)
h = Hash.new{[]} # also does not work as expected (after `x[:a].push(3)`  `x[:a]` would be `[]` not `[3]`)
h = Hash.new{Array.new} # use this one instead

因此在某些情况下使用||= 可能很简单

h = Hash.new
h[:ferrets] ||= 0
h[:ferrets] += 1

【讨论】:

  • 我喜欢您提供的 ||= 解决方案,但很快就删除了。你能解释一下为什么我会使用其中一个吗?默认 val 解决方案和 ||= 对我来说似乎都不错。
  • 实际上,我可以想到我会使用 ||= 的一个原因:如果值的类型很重要并且 nil 对于整理未初始化的内容很重要。不过,默认 val 版本非常适合我的情况。
【解决方案2】:

解决此问题的一种方法是为您的哈希设置默认值:

h = Hash.new
h.default = 0
h[:ferrets] += 1

puts h.inspect
#{:ferrets=>1}

hash 的默认默认值为 nil,nil 不理解如何 ++ 本身。

h = Hash.new{0} 
h = Hash.new(0) # also works (thanks @Phrogz)

是另一种在声明时设置默认值的方法。

【讨论】:

  • 注意,这里没有理由使用块形式。试试Hash.new(0)
  • 谢谢!我总是从这些类型的问题中学到很多东西。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-23
  • 2016-10-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多