Ruby 如何分配哈希[';a';][';b';]=';c';如果散列[';a';]没有';不存在?
有比这更简单的方法吗Ruby 如何分配哈希[';a';][';b';]=';c';如果散列[';a';]没有';不存在?,ruby,hash,variable-assignment,autovivification,hash-of-hashes,Ruby,Hash,Variable Assignment,Autovivification,Hash Of Hashes,有比这更简单的方法吗 if hash.key?('a') hash['a']['b'] = 'c' else hash['a'] = {} hash['a']['b'] = 'c' end 一个简单的,但哈希应该是有效的哈希对象 (hash["a"] ||= {})['b'] = "c" 如果按照以下方式创建散列,默认值为新的(相同的默认值)散列:(感谢Phrogz的更正;我的语法错误) 那你就可以了 hash["a"]["b"] = "c" 无需任何附加代码。最简单的
if hash.key?('a')
hash['a']['b'] = 'c'
else
hash['a'] = {}
hash['a']['b'] = 'c'
end
一个简单的,但哈希应该是有效的哈希对象
(hash["a"] ||= {})['b'] = "c"
如果按照以下方式创建
散列
,默认值为新的(相同的默认值)散列:(感谢Phrogz的更正;我的语法错误)
那你就可以了
hash["a"]["b"] = "c"
无需任何附加代码。最简单的方法是使用块参数:
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所指出的,您可以使用以下方法使自动活跃哈希自动活跃:
更新:我想我应该澄清我对Hash.new({})
的警告。当你这么说的时候:
h = Hash.new({ })
h = Hash.new(0)
这很像是这样说的:
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)
为false
然而,当你这么说的时候:
h = Hash.new({ })
h = Hash.new(0)
一切都会顺利进行,因为您永远不会在此处修改h[k]
,您只会从h
读取一个值(必要时将使用默认值),或为h
指定一个新值此处的问题:
提供了一个非常有用的AutoHash
实现
class NilClass
def [](other)
nil
end
end
一旦定义了它,一切都将自动运行。但是请注意,从现在起,当用作哈希时,nil将表现为空哈希。关键词:“ruby哈希自动活跃自动活跃”(让我们看看如何将它们链接到中——请参见“相关”)@pst:我认为存在编辑冲突-有人修复了一些拼写错误并删除了您的标记。好吧,您可以这样做,但是您的
哈希值不会改变。我想你的意思是:hash=hash.new{h,k{h[k]=hash.new(&h.default_-proc)}
正如你所知,但可能想指出的是,这只会自动激活一个层次的深度,而这样做:hash.new{h,k{h[k]=hash.new(&h.default_-proc)}
是海龟一直在往下走。@mu:很好的解释,但我不明白会对所有默认条目使用完全相同的哈希值。
。我们不希望默认条目相同吗?@Radek:不,您不希望默认条目是相同的对象。如果它们使用的是同一个对象,那么你最终会发现hash['a']
和hash['b']
是同一个对象,而这甚至不会像你希望的那样出现在hash
中。在irb
中尝试我的示例,但是使用Hash.new({})
构造函数,您将看到问题。Hash.new(x)
表单只有在x
类似于Fixnum时才有效。@Radek:And checkHash.inspect
,Hash.default.inspect
,Hash['a'].inspect
和Hash['b']在使用Hash.new({})运行示例后检查
)
@Radek:我添加了一个更新,更好地解释了为什么Hash.new({})
是个坏主意。与使用默认进程相比,这种方法有很大的灵活性。要构造一个默认哈希,仅当k='a'
时,才将h[k]
设置为{}
,需要编写hash.new{| |,k | k='a'?{}:nil}
,这非常难看。另一方面,表达式中的任何或所有字符串都可以是变量,因此它没有任何限制。此外,我还听说,这种方法往往比使用默认过程更快。奇怪的是,'b'
在单引号中,而,…:-)