在任意深度处访问嵌套的哈希值的最红宝石的方式是什么



给定一个哈希,例如:

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在HashArray上引入了一种称为dig的新方法,完全解决了此问题。

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

如果任何级别缺少键,它将返回nil

最新更新