2

这个 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' }}}}

我希望它保留层次结构中存在的任何其他散列值,并根据需要创建新的散列。

我对 ruby​​ 中的元编程相当陌生,感谢 andy 的帮助。

4

2 回答 2

4

完成我认为您想要的一种方法是使用相同的自动激活散列技术,而无需重新定义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']但我认为这是您需要的。

于 2013-03-22T02:28:03.163 回答
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"}}}}
于 2013-03-22T02:02:13.607 回答