Ruby 如何检查散列中的嵌套属性?

Ruby 如何检查散列中的嵌套属性?,ruby,Ruby,我需要检查属性的嵌套哈希 empty = if @body && @body["#{@path}_response".to_sym] && @body["#{@path}_response".to_sym]["#{@path}_result".to_sym] && @body["#{@path}_response".to_sym]["#{@path}_result".to_sym][:error][:

我需要检查属性的嵌套哈希

      empty = if @body &&
      @body["#{@path}_response".to_sym] &&
      @body["#{@path}_response".to_sym]["#{@path}_result".to_sym] &&
      @body["#{@path}_response".to_sym]["#{@path}_result".to_sym][:error][:error_code].eql?'NoAvailibilitiesFound'

            true
          else
            false
          end
我要检查的实际属性是:error。但有可能

@body["#{@path}_response".to_sym]
甚至不存在。因此,我在每个级别中检查属性

      empty = if @body &&
      @body["#{@path}_response".to_sym] &&
      @body["#{@path}_response".to_sym]["#{@path}_result".to_sym] &&
      @body["#{@path}_response".to_sym]["#{@path}_result".to_sym][:error][:error_code].eql?'NoAvailibilitiesFound'

            true
          else
            false
          end

我觉得这有点奇怪。有没有一种优雅的“rubysh”方法可以做得更好?

可能有几种方法可以做到这一点,但目前我能想到的唯一选择是方法。根据文件:

从给定键的哈希中返回一个值。如果钥匙不能打开 找到后,有几个选项:如果没有其他参数,它将 引发keyrerror异常;如果给出默认值,那么将是 返回;如果指定了可选代码块,则将 运行并返回其结果

由于您似乎需要知道
:error\u code
的值是否等于某个值,或者如果它不等于某个值(或者结构不同),则为false,因此我相信您可以使用
KeyError
选项,如果引发异常,则返回false,如下所示:

def your_method
    @body.fetch("#{@path}_response".to_sym).fetch("#{@path}_result".to_sym).fetch(:error).fetch(:error_code).eql? 'NoAvailibilitiesFound'
rescue KeyError
    false
end
h = { a: { b: {c: 1} } } #=> {:a=>{:b=>{:c=>1}}}

h.fetch(:a, {}).fetch(:b, {}).fetch(:c, false) #=> 1
h.fetch(:a, {}).fetch(:b, {}).fetch(:d, false) #=> false
h.fetch(:a, {}).fetch(:d, {}).fetch(:c, false) #=> false
h.fetch(:d, {}).fetch(:b, {}).fetch(:c, false) #=> false
您还可以使用文档中描述的“默认值”选项。然而,刚刚试着给你们写一个例子,我意识到它会变得非常混乱,几乎不可能轻松阅读


就像我说的,可能还有很多其他的方法,但希望这已经足够了。让我知道这是否合理。

我同意@Paul的观点,你应该使用。Paul提到使用默认值,但认为它可能过于复杂。实际上,这非常简单:只需将默认值设为空哈希,如下所示:

def your_method
    @body.fetch("#{@path}_response".to_sym).fetch("#{@path}_result".to_sym).fetch(:error).fetch(:error_code).eql? 'NoAvailibilitiesFound'
rescue KeyError
    false
end
h = { a: { b: {c: 1} } } #=> {:a=>{:b=>{:c=>1}}}

h.fetch(:a, {}).fetch(:b, {}).fetch(:c, false) #=> 1
h.fetch(:a, {}).fetch(:b, {}).fetch(:d, false) #=> false
h.fetch(:a, {}).fetch(:d, {}).fetch(:c, false) #=> false
h.fetch(:d, {}).fetch(:b, {}).fetch(:c, false) #=> false

这里我假设如果键
:a
:b
:c
在各自的级别上存在,则返回
1
;否则将返回
false

Ahh好的,这是有意义的。没有我想的那么糟;在我的版本中,我有更多的垃圾,在报废之前。