【问题标题】:extracting specific value from a multidimensional hash in ruby by key name通过键名从 ruby​​ 中的多维哈希中提取特定值
【发布时间】:2010-02-10 17:18:53
【问题描述】:

假设我有一个多维哈希,并且在其中一个子哈希中我有一个 key=>value 对,我需要通过 key 检索它。我该怎么做?

示例哈希:

h={:x=>1,:y=>2,:z=>{:a=>{:k=>"needle"}}}
h={:k=>"needle"}

key 总是 :k,我需要得到“needle”

我注意到 ruby​​ 1.8 中没有散列的“扁平化”功能,但如果它存在,我想我会这样做

h.flatten[:k]

我想我需要为此编写一个递归函数?

谢谢

【问题讨论】:

    标签: ruby hash hash-of-hashes


    【解决方案1】:

    您始终可以为 Hash 编写自己的特定任务扩展,它会为您完成繁琐的工作:

    class Hash
      def recursive_find_by_key(key)
        # Create a stack of hashes to search through for the needle which
        # is initially this hash
        stack = [ self ]
    
        # So long as there are more haystacks to search...
        while (to_search = stack.pop)
          # ...keep searching for this particular key...
          to_search.each do |k, v|
            # ...and return the corresponding value if it is found.
            return v if (k == key)
    
            # If this value can be recursively searched...
            if (v.respond_to?(:recursive_find_by_key))
              # ...push that on to the list of places to search.
              stack << v
            end
          end
        end
      end
    end
    

    你可以很简单地使用它:

    h={:x=>1,:y=>2,:z=>{:a=>{:k=>"needle"}}}
    
    puts h.recursive_find_by_key(:k).inspect
    # => "needle"
    
    h={:k=>"needle"}
    
    puts h.recursive_find_by_key(:k).inspect
    # => "needle"
    
    puts h.recursive_find_by_key(:foo).inspect
    # => nil
    

    【讨论】:

    • 美丽。正是我想要的。
    • 您会将扩展的“Hash”类(例如在 gem 中)放在哪里,以便其他类可以使用它的方法?
    • 您需要将其加载到某种初始化程序中。 gem 通常有一个主库文件,所以这可能在这里起到作用。要么在那里定义它,要么相应地require它。
    • 您可以将yield if block_given? 添加为方法的最后一行,以实现更完全并行的 Hash#fetch 功能
    【解决方案2】:

    如果你只需要获取key值,但不知道key有多深,使用这个sn-p

    def find_tag_val(hash, tag)
      hash.map do |k, v|
        return v if k.to_sym == tag
        vr = find_tag_val(v, tag) if v.kind_of?(Hash)
        return vr if vr
      end
      nil #othervice
    end 
    
    h = {message: { key: 'val'}}
    find_tag_val(h, :key) #=> 'val'
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-21
      • 1970-01-01
      • 2015-03-16
      • 2021-06-25
      • 2013-03-05
      • 2015-01-20
      相关资源
      最近更新 更多