2010-02-10 37 views
0

比方说,我有一个多维散列,并且在其中一个子哈哈中,我有一个key => value对,我需要通过key来检索。我该怎么做?通过键名从红宝石中的多维哈希中提取特定值

例如哈希:

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

关键始终是:K,我需要得到“针”

我注意到,有使用Ruby 1.8哈希没有“扁平化”的功能,但如果它会在那里,我想我只是做

h.flatten[:k] 

我想我需要写一个递归函数呢?

感谢

回答

9

你总是可以编写自己的具体任务扩展到散列这为你做肮脏的工作:

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 
+0

美丽。正是我在找的东西。 – 2011-01-16 02:12:01

+0

你会在哪里放置扩展的“哈希”类(例如在一个gem中),以便其方法可用于其他类? – thoughtpunch 2011-05-22 03:02:08

+0

你需要将它加载到某种初始化器中。宝石通常有一个主库文件,所以这可能是为了达到这个目的。要么在那里定义它,要么相应地“要求”。 – tadman 2011-05-24 14:04:38

2

如果您只需要获取密钥值,但不知道密钥有多深,请使用此代码段

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'