Ruby 风格:如何检查嵌套的哈希元素是否存在 [英] Ruby Style: How to check whether a nested hash element exists

查看:20
本文介绍了Ruby 风格:如何检查嵌套的哈希元素是否存在的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑一个存储在散列中的人".两个例子是:

Consider a "person" stored in a hash. Two examples are:

fred = {:person => {:name => "Fred", :spouse => "Wilma", :children => {:child => {:name => "Pebbles"}}}}
slate = {:person => {:name => "Mr. Slate", :spouse => "Mrs. Slate"}} 

如果person"没有任何孩子,则children"元素不存在.所以,对于 Slate 先生,我们可以检查他是否有父母:

If the "person" doesn't have any children, the "children" element is not present. So, for Mr. Slate, we can check whether he has parents:

slate_has_children = !slate[:person][:children].nil?

那么,如果我们不知道slate"是一个person"哈希怎么办?考虑:

So, what if we don't know that "slate" is a "person" hash? Consider:

dino = {:pet => {:name => "Dino"}}

我们不能再轻易地检查孩子:

We can't easily check for children any longer:

dino_has_children = !dino[:person][:children].nil?
NoMethodError: undefined method `[]' for nil:NilClass

那么,您将如何检查散列的结构,尤其是如果它嵌套很深(甚至比此处提供的示例更深)?也许更好的问题是:什么是Ruby 方式"来做到这一点?

So, how would you check the structure of a hash, especially if it is nested deeply (even deeper than the examples provided here)? Maybe a better question is: What's the "Ruby way" to do this?

推荐答案

最明显的方法是简单地检查每一步:

The most obvious way to do this is to simply check each step of the way:

has_children = slate[:person] && slate[:person][:children]

.nil 的使用?仅当您使用 false 作为占位符值时才真正需要它,实际上这种情况很少见.通常,您可以简单地测试它是否存在.

Use of .nil? is really only required when you use false as a placeholder value, and in practice this is rare. Generally you can simply test it exists.

更新:如果您使用的是 Ruby 2.3 或更高版本,则有一个内置的 dig 方法,该方法执行此答案中描述的操作.

Update: If you're using Ruby 2.3 or later there's a built-in dig method that does what's described in this answer.

如果没有,您也可以定义自己的哈希挖掘"方法,这可以大大简化:

If not, you can also define your own Hash "dig" method which can simplify this substantially:

class Hash
  def dig(*path)
    path.inject(self) do |location, key|
      location.respond_to?(:keys) ? location[key] : nil
    end
  end
end

这个方法会检查每一步,避免调用 nil 时出错.对于浅层结构,实用性有限,但对于深度嵌套的结构,我发现它是无价的:

This method will check each step of the way and avoid tripping up on calls to nil. For shallow structures the utility is somewhat limited, but for deeply nested structures I find it's invaluable:

has_children = slate.dig(:person, :children)

您还可以使这更加健壮,例如,测试 :children 条目是否实际填充:

You might also make this more robust, for example, testing if the :children entry is actually populated:

children = slate.dig(:person, :children)
has_children = children && !children.empty?

这篇关于Ruby 风格:如何检查嵌套的哈希元素是否存在的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆