从this SO answer开始,我可以动态创建嵌套的哈希值:
hash = Hash.new{ |h,k| h[k] = Hash.new(&h.default_proc) }
例如:
hash = Hash.new{ |h,k| h[k] = Hash.new(&h.default_proc) }
hash['a']['b']['c'] = { 'key' => 'value' }
#=> {'a' => { 'b' => { 'c' => { 'key' => 'value' }}}}
到目前为止一切顺利。
我需要这个:
hash = Hash.new{ |h,k| h[k] = Hash.new(&h.default_proc) }
hash['a', 'b', 'c'] = { 'key' => 'value' }
#=> {'a' => { 'b' => { 'c' => { 'key' => 'value' }}}}
我更喜欢它保留层次结构中存在的任何其他哈希值,并根据需要创建新的哈希值。
我对红宝石中的元编程相当新,我们非常感谢。
答案 0 :(得分:3)
实现我想你想要的一种方法是给予相同的自动生成散列技术,而不必重新定义Hash#[]
就是在给定所需数组的每个元素的情况下简单地遍历散列(更深入)。我能想到的最常用的方法是使用Array#inject
:
# auto-vivifying hash
hash = Hash.new { |h, k| h[k] = Hash.new(&h.default_proc) }
# array of keys
keys = ['a', 'b', 'c']
# "Injection", a.k.a, "go deeper" ;)
keys.inject(hash) {|h, k|
h[k]
}['key'] = 'value' # assign 'value' to 'key' on last/deepest hash
p hash # {"a"=>{"b"=>{"c"=>{"key"=>"value"}}}}
与hash['a', 'b', 'c']
不完全相同(因为这是一个语法错误),但我收集它是你需要的。
答案 1 :(得分:1)
这是我得到的最接近的,却不知道“我更喜欢保留层次结构中存在的任何其他哈希值”的含义。由于某种原因,该方法的返回值并不完美,但我有点太累了,无法找出原因(欢迎任何评论)。
class MyH < Hash
def []= (*keys, value)
self.merge! keys.reverse.inject(value){|mem,obj| {obj => mem } }
self
end
end
hash = MyH.new
# => {}
hash['a', 'b', 'c'] = { 'key' => 'value' }
# => {"key"=>"value"}
hash
# => {"a"=>{"b"=>{"c"=>{"key"=>"value"}}}}