8

给定一个哈希值,例如:

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() 中写的更好的方法。

4

4 回答 4

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

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

于 2012-11-06T21:00:05.473 回答
6
%w[other service secret].inject(AppConfig, &:fetch)
于 2012-11-07T00:55:42.647 回答
1
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"
于 2012-11-06T20:59:11.760 回答
1

Ruby 2.3.0 引入了一种新方法,在这两者上都调用digHash了,Array它完全解决了这个问题。

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

nil如果密钥在任何级别丢失,它就会返回。

于 2016-01-06T03:14:11.953 回答