【问题标题】:How to add values to nested hash on the fly with array of keys?如何使用键数组动态地将值添加到嵌套哈希?
【发布时间】:2013-03-22 10:28:03
【问题描述】:

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

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

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

【问题讨论】:

  • “我希望它保留层次结构中存在的任何其他哈希值”是什么意思?
  • Hash#[](元素引用)方法的元数为 1。也就是说,它只接受一个参数,并且不能像你写的那样接受多个参数:hash['a', 'b', 'c'] = ...。如果你传入一个数组,就像 hash[['a', 'b', 'c']] = ... 那样,那么默认值块将不会被调用,因为你没有引用一个不存在的键,你直接使用给定键 ['a', 'b', 'c'] 分配一个值,这只是恰好是一个数组。
  • AlistairIsrael - 我如何使用 ['a', 'b', 'c'] 作为哈希 ['a']['b']['c']?那将解决我的问题。我需要一种以编程方式执行此操作的方法。

标签: ruby-on-rails ruby


【解决方案1】:

实现我认为您想要的一种方法是使用相同的自动激活哈希技术,而无需重新定义 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'] 不太一样(因为这是一个语法错误),但我认为这正是您所需要的。

【讨论】:

  • 正是我需要的,尽管我的问题问得不好,但你看出了我需要什么。谢谢!
【解决方案2】:

这是我得到的最接近的,但不知道“我希望它保留层次结构中存在的任何其他哈希值”究竟是什么意思。由于某种原因,该方法的返回值并不完美,但我有点太累了,无法弄清楚原因(欢迎任何关于为什么的 cmets)。

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"}}}}

【讨论】:

    猜你喜欢
    • 2018-04-21
    • 2014-04-28
    • 1970-01-01
    • 1970-01-01
    • 2012-03-13
    • 2012-08-07
    • 2020-06-08
    • 2020-10-14
    • 2017-12-11
    相关资源
    最近更新 更多