如何使用Ruby 2.3中引入的`Array#dig`和`Hash#dig`? [英] How do I use `Array#dig` and `Hash#dig` introduced in Ruby 2.3?
问题描述
Ruby 2.3在 Array
和 Hash
中引入了一种新方法,称为 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
我没有使用三重嵌套平面数组。什么是一个现实的例子,如何这将是有用的?
更新
它原来这些方法解决了最常见的Ruby问题之一。下面的问题有20个重复的东西,所有这些都是通过使用 dig
来解决的:
如何避免NoMethodError嵌套哈希中缺少的元素,没有重复无检查?
在我们的例子中,由于 nil
引用, NoMethodError
s是迄今为止我们看到的最常见的错误我们的生产环境。
新的 Hash#dig
允许您省略 nil
在访问嵌套元素时进行检查。由于散列最适用于数据结构未知或不稳定的情况,因此对此提供官方支持很有意义。
让我们来看你的例子。以下内容:
user.dig(:user,:address,:street1)
不是相当于:
user [:user] [:address] [:street1]
其中用户[:用户]
或用户[:用户] [:地址]
是无
相当于下面这个当前的习惯用法:
user [:user]&&用户[:用户] [:地址]&& user [:user] [:address] [:street1]
注意如何通过其他地方创建的符号列表 Hash#dig
,但从这样的列表重新创建后一个构造并不是非常简单。 Hash#dig
允许您轻松进行动态访问,而无需担心 nil
引用。
显然 Hash#dig
也短得多。
需要注意的一点是 Hash#dig
本身会返回 nil
if任何一个键都会变成这样,这会导致相同类型的错误,因此提供一个合理的默认值是一个不错的主意。 (这种提供对象总是响应所期望的方法的方式称为空对象模式。)
再次,在你的例子中,一个空字符串或者类似N / A的东西,取决于什么是合理的:
user.dig(:user,:address,:street1)||
Ruby 2.3 introduces a new method on Array
and Hash
called dig
. The examples I've seen in blog posts about the new release are contrived and convoluted:
# 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
I'm not using triple-nested flat arrays. What's a realistic example of how this would be useful?
UPDATE
It turns out these methods solve one of the most commonly-asked Ruby questions. The questions below have something like 20 duplicates, all of which are solved by using dig
:
How to avoid NoMethodError for missing elements in nested hashes, without repeated nil checks?
Ruby Style: How to check whether a nested hash element exists
In our case, NoMethodError
s due to nil
references are by far the most common errors we see in our production environments.
The new Hash#dig
allows you to omit nil
checks when accessing nested elements. Since hashes are best used for when the structure of the data is unknown, or volatile, having official support for this makes a lot of sense.
Let's take your example. The following:
user.dig(:user, :address, :street1)
Is not equivalent to:
user[:user][:address][:street1]
In the case where user[:user]
or user[:user][:address]
is nil
, this will result in a runtime error.
Rather, it is equivalent to the following, which is the current idiom:
user[:user] && user[:user][:address] && user[:user][:address][:street1]
Note how it is trivial to pass a list of symbols that was created elsewhere into Hash#dig
, whereas it is not very straightforward to recreate the latter construct from such a list. Hash#dig
allows you to easily do dynamic access without having to worry about nil
references.
Clearly Hash#dig
is also a lot shorter.
One important point to take note of is that Hash#dig
itself returns nil
if any of the keys turn out to be, which can lead to the same class of errors one step down the line, so it can be a good idea to provide a sensible default. (This way of providing an object which always responds to the methods expected is called the Null Object Pattern.)
Again, in your example, an empty string or something like "N/A", depending on what makes sense:
user.dig(:user, :address, :street1) || ""
这篇关于如何使用Ruby 2.3中引入的`Array#dig`和`Hash#dig`?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!