21

有没有比这更简单的方法

if hash.key?('a')
  hash['a']['b'] = 'c' 
else  
  hash['a'] = {}
  hash['a']['b'] = 'c' 
end
4

5 回答 5

39

最简单的方法是使用块参数构造 Hash :

hash = Hash.new { |h, k| h[k] = { } }
hash['a']['b'] = 1
hash['a']['c'] = 1
hash['b']['c'] = 1
puts hash.inspect
# "{"a"=>{"b"=>1, "c"=>1}, "b"=>{"c"=>1}}"

此表单用于new创建一个新的空哈希作为默认值。你不想要这个:

hash = Hash.new({ })

因为这将对所有默认条目使用完全相同的哈希。

此外,正如 Phrogz 所指出的,您可以使用以下方法使自动激活的哈希自动激活default_proc

hash = Hash.new { |h, k| h[k] = Hash.new(&h.default_proc) }

更新:我想我应该澄清我的警告Hash.new({ })。当你这样说时:

h = Hash.new({ })

这很像这样说:

h = Hash.new
h.default = { }

然后,当您访问h将某些内容分配为h[:k][:m] = y时,它的行为就好像您这样做了:

if(h.has_key?(:k))
    h[:k][:m] = y
else
    h.default[:m] = y
end

然后,如果你h[:k2][:n] = z,你最终会分配h.default[:n] = z. 请注意,h仍然说这h.has_key?(:k)是错误的。

然而,当你这样说:

h = Hash.new(0)

一切都会好起来的,因为您永远不会h[k]在此处进行修改,您只会从中读取一个值h(必要时将使用默认值)或为h.

于 2011-05-04T04:42:26.733 回答
10

一个简单的,但哈希应该是一个有效的哈希对象

(hash["a"] ||= {})['b'] = "c"
于 2011-05-04T04:36:38.190 回答
2

如果您创建hash如下,使用新的(相同的默认值)哈希的默认值:(感谢 Phrogz 的更正;我的语法错误)

hash = Hash.new{ |h,k| h[k] = Hash.new(&h.default_proc) }

然后你可以做

hash["a"]["b"] = "c"

没有任何额外的代码。

于 2011-05-04T04:41:20.983 回答
0

这里的问题 是:在 Ruby 中是否可以像在 PHP 中那样自动初始化多维哈希数组? 提供了一个非常有用的AutoHash实现。

于 2014-11-24T06:07:35.077 回答
0
class NilClass
  def [](other)
    nil
  end
end

一旦你定义了,一切都会自动运行。但请注意,从现在开始,nil当用作散列时,它的行为将表现为空散列。

于 2016-05-14T17:33:02.193 回答