在任意深度访问嵌套哈希值的最ruby方法是什么?

给出如下的哈希:

AppConfig = { 'service' => { 'key' => 'abcdefg', 'secret' => 'secret_abcdefg' }, 'other' => { 'service' => { 'key' => 'cred_abcdefg', 'secret' => 'cred_secret_abcdefg' } } } 

在某些情况下我需要一个函数来返回服务/密钥,在其他情况下我需要其他/ service / key。 一种简单的方法是传入散列和一组键,如下所示:

 def val_for(hash, array_of_key_names) h = hash array_of_key_names.each { |k| h = h[k] } h end 

这样调用会导致’cred_secret_abcdefg’:

 val_for(AppConfig, %w[other service secret]) 

似乎应该有比我在val_for()中写的更好的方法。

 def val_for(hash, keys) keys.reduce(hash) { |h, key| h[key] } end 

如果找不到某个中间键,这将引发exception。 另请注意,这完全等同于keys.reduce(hash, :[]) ,但这可能会让一些读者感到困惑,我会使用该块。

 %w[other service secret].inject(AppConfig, &:fetch) 
 appConfig = { 'service' => { 'key' => 'abcdefg', 'secret' => 'secret_abcdefg' }, 'other' => { 'service' => { 'key' => 'cred_abcdefg', 'secret' => 'cred_secret_abcdefg' } } } def val_for(hash, array_of_key_names) eval "hash#{array_of_key_names.map {|key| "[\"#{key}\"]"}.join}" end val_for(appConfig, %w[other service secret]) # => "cred_secret_abcdefg" 

Ruby 2.3.0在HashArray上引入了一个名为dig的新方法 ,完全解决了这个问题。

 AppConfig.dig('other', 'service', 'secret') 

如果在任何级别缺少密钥,则返回nil