什么是在任意深度嵌套访问散列值的最红宝石十岁上下的方式吗? [重复](What is the m

2019-07-03 14:35发布

这个问题已经在这里有一个答案:

  • 如何避免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一个更好的方法()。

Answer 1:

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

如果某些中间关键是没有找到这将引发异常。 还需要注意的是,这是完全等同于keys.reduce(hash, :[])但是这很可能混淆了一些读者,我会使用该块。



Answer 2:

%w[other service secret].inject(AppConfig, &:fetch)


Answer 3:

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"


Answer 4:

红宝石2.3.0推出了一个所谓的新方法dig两个HashArray是完全解决了这个问题。

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

它返回nil ,如果该键在任何级别的缺失。



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