如何测试Ruby中是否存在三维哈希值

如何测试Ruby中是否存在三维哈希值,ruby,Ruby,我有一个散列变量,它可以以两种方式存在:一个一维散列变量,比如 myvar['level1'] myvar['level1']['level2']['level3'] 它总是存在,或者是一个三维散列 myvar['level1'] myvar['level1']['level2']['level3'] 可能存在也可能不存在。2级成员可能在那里,有时与其他成员在一起。现在,如果我想测试level3成员是否存在,我使用如下代码 if myvar['level1']['level2'] !=

我有一个散列变量,它可以以两种方式存在:一个一维散列变量,比如

myvar['level1']
myvar['level1']['level2']['level3']
它总是存在,或者是一个三维散列

myvar['level1']
myvar['level1']['level2']['level3']
可能存在也可能不存在。2级成员可能在那里,有时与其他成员在一起。现在,如果我想测试level3成员是否存在,我使用如下代码

if myvar['level1']['level2'] != nil?
   if myvar['level1']['level2']['level3'] != nil?
      ....
因为当我访问level3成员而没有level2成员时,我将收到一个错误。我想知道是否有一种方法可以在不首先测试第二个成员的情况下测试level3成员的存在?

不,这是不可能的。“level3”仅与“level2”相关,因此必须在之前检查它。 您可以使测试看起来更好,但首先需要测试“level2”的存在。 我可以推荐一个更好的版本,但它是众多版本中的一个

if l1 = mayvar['level1'] && l2 = l1['level2'] && l2['level3']
...
这是一种方式:

def extract_values(h,keys)
  keys.reduce(h) { |g,k| ((g.is_a? Hash) ? g : {})[k] }
end

h = {a: {b: {c: "The End"} } }

extract_values(h,[])               #=> {:a=>{:b=>{:c=>"The End"}}}
extract_values(h,[:a])             #=> {:b=>{:c=>"The End"}}
extract_values(h,[:a, :b])         #=> {:c=>"The End"}
extract_values(h,[:a, :b, :c])     #=> "The End"
extract_values(h,[:a, :z, :c])     #=> nil
extract_values(h,[:a, :b, :c, :d]) #=> nil

这样的话,我仍然在学习两行代码,它基本上与我现在测试的代码相同,但可读性较差。如果您有
级别=%w{level1 level2 level3 level4}
,而
h
没有该级别,这将不起作用。谢谢,@sawa。在我看来,这种方法的主要好处是它可以处理任意数量的级别。这是一种非常好的结构化解决方案,应该是基本语言结构imho的一部分。将其添加到我的默认库中!