如何使用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屋!