What is the most ruby-ish way of accessing nested hash values at arbitrary depths? [duplicate]

不羁的心 提交于 2019-11-30 19:32:20
def val_for(hash, keys)
  keys.reduce(hash) { |h, key| h[key] }
end

This will raise an exception if some intermediate key is not found. Note also that this is completely equivalent to keys.reduce(hash, :[]), but this may very well confuse some readers, I'd use the block.

%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 introduced a new method called dig on both Hash and Array that solves this problem entirely.

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

It returns nil if the key is missing at any level.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!