如何检查ruby散列成员是否递归存在?
问题描述:
这有点让人困惑。如何检查ruby散列成员是否递归存在?
如果你有一个散列,其中包含更多的散列,也有散列等,你如何确定一个成员是否存在超过一层深?
例如:
hash 1 =
{
"layer1" =>
{
"layer2" =>
{
"layer3" => ['Something', 'Array']
}
}
}
,你会如何去验证“东西”存在于上述哈希如果哈希只有:
hash2 =
{
"layer1" =>
{
"layer2" => ['Other Array']
}
}
例如,我会尝试做:
if hash2['layer1']['layer2']['layer3'].contains? 'Something'
puts "Found Something!"
end
但这会错误未定义的方法`包含?'为零:NilClass。其中layer3将是NilClass,因为它不存在。如果其中一个嵌入式哈希值为零,则表明它不存在,但您不能轻易测试它们的存在,因为如果您的图层太深,它也会返回Nil。在ruby中是否有一个函数以递归方式检查每个顶层图层,而不是在您要调用.nil时请求的特定成员? E.g.我认为会起作用的!
if hash2['layer1']['layer2']['layer3'].nil?
puts 'layer3 exists'
end
但是.nil? 只有检查'layer3'是否存在。是否有一种方法从'layer1'开始,然后检查'layer2'是否存在,然后是'layer3'等等。在任何部分都是零,它返回false?因为如果'layer2'或'layer1'不存在,它会在nil:NilClass中错误地指出未定义的方法`[]'。
答
结账Hash#dig()
。它需要一组键并递归查找它们,如果其中任何一个丢失,则返回nil
。从文档:
h = { foo: {bar: {baz: 1}}}
h.dig(:foo, :bar, :baz) #=> 1
h.dig(:foo, :zot) #=> nil
只是注意,如果baz
为nil
,首先通话将返回nil
。所以如果你知道你的哈希中不存在nil
,它只是替代检查是否存在嵌套键。
答
不是最好的解决办法,但我写了这个:
h = {"layer1"=>
{"layer2"=>
{"layer3"=>["Something", "Array"]}
},
"layerx" => ["d"],
"layerz" => {"layera" => "deep"}
}
def vals(h)
return h if !h.is_a?(Hash)
h.values.map(&method(:vals)).flatten
end
vals(h) #=> ["Something", "Array", "d", "deep"]
vals
给人深刻的嵌套哈希-ES值。你可以检查你的元素是否在那里。
https://*.com/q/8301566/5101493可能会帮助 –