8

次のようなハッシュが与えられます:

AppConfig = {
  'service' => {
    'key' => 'abcdefg',
    'secret' => 'secret_abcdefg'
  },
  'other' => {
    'service' => {
      'key' => 'cred_abcdefg',
      'secret' => 'cred_secret_abcdefg'
    }
  }
}

ある場合にはservice/keyを返し、他の場合にはother / service/keyを返す関数が必要です。簡単な方法は、次のようにハッシュとキーの配列を渡すことです。

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では、両方で呼び出される新しいメソッドがdig導入されました。これにより、この問題が完全に解決されます。HashArray

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

nilキーがいずれかのレベルで欠落している場合に返されます。

于 2016-01-06T03:14:11.953 に答える