如何使用Ruby 2.3中引入的`Array#dig`和`Hash#dig`?

Ruby 2.3在ArrayHash上引入了一种名为dig的新方法。 我在关于新版本的博客文章中看到的例子是人为的,令人费解的:

 # Hash#dig user = { user: { address: { street1: '123 Main street' } } } user.dig(:user, :address, :street1) # => '123 Main street' # Array#dig results = [[[1, 2, 3]]] results.dig(0, 0, 0) # => 1 

我没有使用三嵌套平面数组。 什么是如何有用的现实例子?

UPDATE

事实certificate,这些方法解决了一个最常见的Ruby问题。 下面的问题有20个重复,所有这些都是通过使用dig解决的:

如何避免NoMethodError在嵌套哈希中缺少元素,而不重复nil检查?

Ruby Style:如何检查嵌套的哈希元素是否存在

在我们的例子中,由于nil引用而导致的NoMethodError是我们在生产环境中看到的最常见的错误。

新的Hash#dig允许您在访问嵌套元素时省略nil检查。 由于哈希最适合用于数据结构未知或易变的情况,因此对此有官方支持非常有意义。

我们举个例子吧。 下列:

 user.dig(:user, :address, :street1) 

等于:

 user[:user][:address][:street1] 

user[:user]user[:user][:address]nil ,这将导致运行时错误。

相反,它等同于以下,这是当前的习语:

 user[:user] && user[:user][:address] && user[:user][:address][:street1] 

注意将在其他地方创建的符号列表传递给Hash#dig是多么微不足道,而从这样的列表重新创建后一个构造并不是非常简单。 Hash#dig允许您轻松进行动态访问,而无需担心nil引用。

显然Hash#dig也很短。


需要注意的一点是,如果任何一个键结果是Hash#dig本身返回nil ,这可能导致同一类错误一步,所以提供一个是一个好主意。合理的默认。 (这种提供始终响应预期方法的对象的方式称为Null对象模式 。)

同样,在您的示例中,空字符串或类似“N / A”的内容,具体取决于有意义的内容:

 user.dig(:user, :address, :street1) || "" 

一种方法是结合splat操作符从一些未知文档模型中读取。

 some_json = JSON.parse( '{"people": {"me": 6, ... } ...}' ) # => "{"people" => {"me" => 6, ... }, ... } a_bunch_of_args = response.data[:query] # => ["people", "me"] some_json.dig(*a_bunch_of_args) # => 6