如何递归检查ruby哈希成员是否存在?

jSt*_*aff 0 ruby hash null

这有点令人困惑。

如果你有一个包含更多散列的散列,这些散列也有散列等等,你如何确定是否存在一个多于一层的成员?

例如:

hash 1 =
{
    "layer1" => 
    {
        "layer2" => 
        {
            "layer3" => ['Something', 'Array']
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

你怎么会去核实“东西”在上面散存在如果哈希只有:

hash2 =
{
    "layer1" => 
    {
        "layer2" => ['Other Array']
    }
}
Run Code Online (Sandbox Code Playgroud)

例如,我会尝试这样做:

if hash2['layer1']['layer2']['layer3'].contains? 'Something'
  puts "Found Something!"
end
Run Code Online (Sandbox Code Playgroud)

但这会错误未定义的方法“包含?” 对于 nil:NilClass。其中 layer3 将是 NilClass 因为它不存在。如果这些嵌入的哈希中的一个是 Nil 然后说它不存在就足够了,但是您无法轻松测试它们的存在,因为如果您的层太深,这也会返回 Nil。ruby 中是否有一个函数可以递归地检查每个顶层的 Nil,而不是调用 .nil 时请求的特定成员?例如,我认为会起作用的!

if hash2['layer1']['layer2']['layer3'].nil?
  puts 'layer3 exists'
end
Run Code Online (Sandbox Code Playgroud)

但是.nil?检查“layer3”是否存在。是否有一种方法从“layer1”开始,然后检查“layer2”是否存在,然后“layer3”等等。并且在任何部分为零它返回假?因为如果 'layer2' 或 'layer1' 不存在,它会报错说 undefined method '[]' for nil:NilClass。

Xav*_*olt 5

退房Hash#dig()。它接受一组键并递归查找它们,nil如果其中任何一个丢失则返回。从文档:

h = { foo: {bar: {baz: 1}}}

h.dig(:foo, :bar, :baz)           #=> 1
h.dig(:foo, :zot)                 #=> nil
Run Code Online (Sandbox Code Playgroud)

请注意,如果baznil,则第一个dig调用会返回nil。因此,如果您知道不会将nils 存储在哈希中,则它只是检查嵌套键是否存在的替代方法。