2013-07-08 101 views
2

在Ruby中,我想要做这样的事情,红宝石使用数组tvalues索引嵌套哈希散列

我有一个这样构建的哈希散列。

h = {1 => {2 => {3 => "three"}},'a' => { 'b' => { 'c' => "basd"}}} 
=> {"a"=>{"b"=>{"c"=>"basd"}}, 1=>{2=>{3=>"three"}}} 

如果我有一个这样的值的数组。

a = [1, 2, 3] 

我想要将使用数组值索引嵌套键在我的散列以及如返回由最后一个键指向的值(由先前的阵列/键作为引导) 的方法。

getHashValue([1,2,3]) should return "three" => h[1][2][3] 

if a = ['a','b', 'c']那么返回值应该是basd

如何完成这项工作?

回答

4

然后还有:

keys.inject(hash, :fetch) 

或更早版本的Ruby:

keys.inject(hash) {|h, k| h[k]} 

如果你确实想用递归,更Rubyesque办法将成为:

def get_value(obj, keys) 
    keys.empty? ? obj : get_value(obj[keys[0]], keys[1..-1]) 
end 
+0

我的尝试中有任何错误? irb(main):2552:0> h => {“a”=> {“b”=> {“c”=>“basd”}},1 => {2 => {3 =>“three (主):2553:0> a = [1,2,3] => [1,2,3] irb(main):2554:0> a.inject(h, (irb):2554:in inject' from(irb):2554 irb(main):2555:0> a.inject(h, :fetch) ArgumentError:错误的参数数量(2为1) from(irb):2555:在'inject' from(irb):2555 – user2562153

+0

@ user2562153我从Ruby 1.9.3开始。所以如果是这种情况,请使用* megar *解决方案。 –

+0

在早期版本的Ruby中,比如你的注入需要一个块,所以你必须使用的表单是'keys.inject(hash){| h,k | h [k]}' –

2

简单而又重复的

def getValue(hash, keys, i = 0) 
    if i + 1 < keys.length 
    getValue(hash[keys[i]], keys, i + 1) 
    else 
    hash[keys[i]] 
    end 
end 

getValue(h, [1,2,3]) => "three" 
getValue(h, ['a','b','c']) => "basd" 
+0

谢谢。有效。 – user2562153

1
h = {1 => {2 => {3 => "three"}},'a' => { 'b' => { 'c' => "basd"}}} 
a = ['a','b', 'c'] 
a.inject(h, :[]) # => "basd" 

h = {1 => {2 => {3 => "three"}},'a' => { 'b' => { 'c' => "basd"}}} 
a = [1, 2, 3] 
a.inject(h, :[]) # => "three" 
+0

嗨Priti,我从上面的注入操作中得到“ArgumentError:错误的参数数目(2 for 1)”。在我的尝试或理解中有任何错误? – user2562153

+0

@ user2562153你现在在做什么'ruby'版本? –

+0

红宝石1.8.6(2009-08-04 patchlevel 383)[x86_64-linux] – user2562153

1

的Ruby 2.3.0上都HashArray是完全解决了这个问题介绍a new method called dig

如果在任何嵌套级别都缺少元素,则返回nil

h1 = {} 
h2 = { a: {} } 
h3 = { a: { b: {} } } 
h4 = { a: { b: { c: 100 } } } 

h1.dig(:a, :b, :c) # => nil 
h2.dig(:a, :b, :c) # => nil 
h3.dig(:a, :b, :c) # => nil 
h4.dig(:a, :b, :c) # => 100