2014-09-03 68 views
2

我有大量的嵌套鍵值對。例如,使用數組中的鍵訪問哈希

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" 

這看起來像一個黑客。此外,它大大降低了我在真實環境中使用散列的能力。

請建議備用和更好的方法。

回答

7

使用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" 

UPDATE

如果你想要做的事,如: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" 
+0

哇..那麼容易!我以爲我在問一個相當棘手的問題。 :P – shivam 2014-09-03 14:55:59

+0

有兩個問題:1>我仍然沒有作爲'h [「foo」] [「bar」] [「hello」] [「world」]來訪問它'所以如果我想操縱散列,我將不能這樣做。 2>它操縱的原始散列不是所需的東西。 – shivam 2014-09-03 15:02:12

+0

@shivam,你是什麼意思是操縱原始散列?它不會除非你使用舊版本的Ruby。如果是這種情況,請使用其他名稱代替塊中的'h':'keys_arr.inject(h){| x,k | x [k]}' – falsetru 2014-09-03 15:04:18

2
keys_arr.inject(h, :[]) 

會做

0

另一種方式:

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