如何递归检查ruby hash成员是不是存在?
Posted
技术标签:
【中文标题】如何递归检查ruby hash成员是不是存在?【英文标题】:How to check if ruby hash member exists recursively?如何递归检查ruby hash成员是否存在? 【发布时间】:2018-03-18 12:02:46 【问题描述】:这有点令人困惑。
如果你有一个哈希包含更多的哈希也有哈希等等,你如何确定一个成员是否存在超过一层深度?
例如:
hash 1 =
"layer1" =>
"layer2" =>
"layer3" => ['Something', 'Array']
如果哈希只有:
,您将如何验证上述哈希中是否存在 'Something':hash2 =
"layer1" =>
"layer2" => ['Other Array']
例如,我会尝试这样做:
if hash2['layer1']['layer2']['layer3'].contains? 'Something'
puts "Found Something!"
end
但这会报错未定义的方法“包含?”对于 nil:NilClass。其中 layer3 将是 NilClass 因为它不存在。如果这些嵌入的哈希值之一是 Nil 就足够了,然后说它不存在,但你不能轻易测试它们的存在,因为如果你的层太深,这也会返回 Nil。 ruby 中是否有一个函数可以递归地检查每个顶层的 Nil,而不是在调用 .nil 时请求的特定成员? 例如我认为可行的方法!
if hash2['layer1']['layer2']['layer3'].nil?
puts 'layer3 exists'
end
但是.nil? 仅检查“layer3”是否存在。是否有一种方法从“layer1”开始,然后检查“layer2”是否存在,然后检查“layer3”等等。并且在任何部分都为零它返回false?因为如果 'layer2' 或 'layer1' 不存在,它会报错为 nil:NilClass 说未定义的方法 `[]'。
【问题讨论】:
***.com/q/8301566/5101493 可能会有所帮助 【参考方案1】:查看Hash#dig()
。它需要一组键并递归查找它们,如果其中任何一个缺失,则返回nil
。来自文档:
h = foo: bar: baz: 1
h.dig(:foo, :bar, :baz) #=> 1
h.dig(:foo, :zot) #=> nil
请注意,如果baz
是nil
,则第一个dig
调用将返回nil
。因此,如果您知道不会将 nil
s 存储在哈希中,则它只是检查是否存在嵌套键的替代品。
【讨论】:
.dig
太棒了!另请记住,它仅适用于 2.3+ 版本。如果这是在 gem 或其他库中,它将不适用于以前版本的用户。
天啊,这正是我想要的。很难找到这个问题的解决方案,因为这个问题的表述方式可能会导致很多不同的版本。【参考方案2】:
不是最好的解决方案,但我写了这个:
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
给出嵌套在哈希内部深处的值。你可以检查你的元素是否在那里。
【讨论】:
以上是关于如何递归检查ruby hash成员是不是存在?的主要内容,如果未能解决你的问题,请参考以下文章