2010-02-10 39 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'