如何对嵌套哈希使用fetch方法?

我有以下哈希:

hash = {'name' => { 'Mike' => { 'age' => 10, 'gender' => 'm' } } } 

我可以通过以下方式访问年龄:

 hash['name']['Mike']['age'] 

如果我使用Hash#fetch方法怎么办? 如何从嵌套哈希中检索密钥?

正如塞尔吉奥所说,做到这一点的方式(不为自己创造一些东西)将是一系列的fetch方法:

 hash.fetch('name').fetch('Mike').fetch('age') 

我所知道的没有内置方法。 我在我目前的项目中有这个

 class Hash def fetch_path(*parts) parts.reduce(self) do |memo, key| memo[key.to_s] if memo end end end # usage hash.fetch_path('name', 'Mike', 'age') 

您可以轻松修改它以使用#fetch而不是#[] (如果您愿意)。

从Ruby 2.3.0开始,你可以使用Hash#dig

 hash.dig('name', 'Mike', 'age') 

它还带来额外的好处,如果沿途的某些值变为nil ,您将获得nil而不是exception。

在迁移之前,您可以使用ruby_dig gem。

如果您的目标是在缺少任何中间键时引发KeyError ,那么您需要编写自己的方法。 如果您使用fetch为缺失键提供默认值,那么您可以通过使用默认值构造Hashes来绕过fetch的使用。

 hash = Hash.new { |h1, k1| h1[k1] = Hash.new { |h2, k2| h2[k2] = Hash.new { |h3, k3| } } } hash['name']['Mike'] # {} hash['name']['Steve']['age'] = 20 hash # {"name"=>{"Mike"=>{}, "Steve"=>{"age"=>20}}} 

这对于任意嵌套的Hashes不起作用,您需要在构造它们时选择最大深度。

从Ruby 2.3.0开始:

你也可以使用&. 称为“安全导航操作员”为: hash&.[]('name')&.[]('Mike')&.[]('age') 。 这个非常安全。

使用dig不安全的,因为如果hash为nil, hash.dig(:name, :Mike, :age)将失败。

但是,您可以将两者合并为: hash&.dig(:name, :Mike, :age)

因此,以下任何一种都可以安全使用:

hash&.[]('name')&.[]('Mike')&.[]('age')

hash&.dig(:name, :Mike, :age)

如果你可以的话

使用:

 hash[["ayy","bee"]] 

代替:

 hash["ayy"]["bee"] 

它会节省很多烦恼