这个问题已经在这里有一个答案:
- 如何避免NoMethodError失踪嵌套哈希元素,无需反复零检查? 17个回答
给定一个散列如:
AppConfig = {
'service' => {
'key' => 'abcdefg',
'secret' => 'secret_abcdefg'
},
'other' => {
'service' => {
'key' => 'cred_abcdefg',
'secret' => 'cred_secret_abcdefg'
}
}
}
我需要的功能在某些情况下,在其他情况下,其他/服务/键返回服务/键。 一个直接的方法是在散和键阵列,像这样通过:
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
如果某些中间关键是没有找到这将引发异常。 还需要注意的是,这是完全等同于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"
红宝石2.3.0推出了一个所谓的新方法dig
两个Hash
和Array
是完全解决了这个问题。
AppConfig.dig('other', 'service', 'secret')
它返回nil
,如果该键在任何级别的缺失。
文章来源: What is the most ruby-ish way of accessing nested hash values at arbitrary depths? [duplicate]