给定一个哈希,例如:
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"
ruby 2.3.0在Hash
和Array
上引入了一种称为dig
的新方法,完全解决了此问题。
AppConfig.dig('other', 'service', 'secret')
如果任何级别缺少键,它将返回nil
。