如何使用 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
.我在有关新版本的博客文章中看到的示例是人为的和令人费解的:
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?
更新
事实证明,这些方法解决了最常见的 Ruby 问题之一.下面的问题大约有 20 个重复,所有这些都使用 dig
解决:
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
:
如何避免 NoMethodError嵌套散列中缺少元素,没有重复的 nil 检查?
推荐答案
在我们的例子中,由于 nil
引用导致的 NoMethodError
是迄今为止我们看到的最常见的错误在我们的生产环境中.
In our case, NoMethodError
s due to nil
references are by far the most common errors we see in our production environments.
新的 Hash#dig
允许您在访问嵌套元素时省略 nil
检查.由于哈希最适合用于数据结构未知或易变的情况,因此获得官方支持非常有意义.
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)
不等价于:
user[:user][:address][:street1]
在 user[:user]
或 user[:user][:address]
为 nil
的情况下,这将导致运行时错误.
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]
请注意,将在别处创建的符号列表传递到 Hash#dig
中是多么的微不足道,而从这样的列表中重新创建后一个构造并不是很简单.Hash#dig
允许您轻松进行动态访问,而不必担心 nil
引用.
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.
显然 Hash#dig
也更短.
需要注意的一个重要点是 Hash#dig
本身返回 nil
如果任何一个键结果是,这可能导致同一类错误一步到位,因此提供合理的默认值可能是一个好主意.(这种提供始终响应预期方法的对象的方式称为 空对象模式.)
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.)
同样,在你的例子中,一个空字符串或类似N/A"的东西,取决于什么是有意义的:
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屋!