如何对嵌套哈希使用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"]
它会节省很多烦恼