【问题标题】:visiting hash with keys from array使用数组中的键访问哈希
【发布时间】:2014-09-03 14:48:59
【问题描述】:

我有一个包含大量嵌套键值对的大哈希。 例如。

h = {"foo" => {"bar" => {"hello" => {"world" => "result" } } } }

现在我想访问result,并且我在数组中有正确顺序的键。

keys_arr = ["foo", "bar", "hello", "world"]

动机很明确,我想做以下事情:

h["foo"]["bar"]["hello"]["world"]
# => "result"

但我不知道该怎么做。我目前正在做:

key = '["' +  keys_arr.join('"]["') + '"]'
eval("h"+key)
# => "result"

这看起来像一个黑客。它也大大降低了我在真实环境中使用哈希的能力。

请提出替代和更好的方法。

【问题讨论】:

    标签: ruby arrays hash ruby-1.8.7


    【解决方案1】:

    使用Enumerable#inject(或Enumerable#reduce):

    h = {"foo" => {"bar" => {"hello" => {"world" => "result" } } } }
    keys_arr = ["foo", "bar", "hello", "world"]
    keys_arr.inject(h) { |x, k| x[k] }
    # => "result"
    

    更新

    如果你想做类似的事情:h["foo"]["bar"]["hello"]["world"] = "ruby"

    innermost = keys_arr[0...-1].inject(h) { |x, k| x[k] } # the innermost hash
    innermost[keys_arr[-1]] = "ruby"
    

    【讨论】:

    • 哇.. 太简单了!!我以为我在问一个相当棘手的问题。 :P
    • 两个问题:1> 我仍然没有以h["foo"]["bar"]["hello"]["world"] 的身份访问它,所以如果我想操纵哈希,我将无法这样做。 2> 它正在操纵原始哈希,这不是我们想要的。
    • @shivam,你是什么意思它正在操纵原始哈希?除非您使用旧版本的 Ruby,否则不会。如果是这种情况,请在块中使用其他名称而不是 hkeys_arr.inject(h) { |x, k| x[k] }
    • @shivam,对于第一个问题,试试这个:innermost = keys_arr[0...-1].inject(h) { |x, k| x[k] }; innermost[keys_arr[-1]] = "ruby"innermost 将引用最里面的哈希对象)
    • 是的,你是对的。我正在使用 ruby​​ 1.8.7 并将名称更改为 x 确实解决了这个问题。谢谢
    【解决方案2】:
    keys_arr.inject(h, :[])
    

    会的

    【讨论】:

      【解决方案3】:

      另一种方式:

      h = {"foo" => {"bar" => {"hello" => {"world" => 10 } } } }
      keys = ["foo", "bar", "hello", "world"]
      
      result = h
      
      keys.each do |key|
        result = result[key]
      end
      
      puts result  #=>10
      

      如果密钥可能不存在,请参见此处:

      Dealing with many [...] in Ruby

      【讨论】:

        猜你喜欢
        • 2013-03-22
        • 2011-12-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-06-26
        • 2013-07-27
        • 1970-01-01
        • 2016-12-12
        相关资源
        最近更新 更多