如何使用Ruby 2.3中引入的`Array#dig`和`Hash#dig`? [英] How do I use `Array#dig` and `Hash#dig` introduced in Ruby 2.3?

查看:126
本文介绍了如何使用Ruby 2.3中引入的`Array#dig`和`Hash#dig`?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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嵌套哈希中缺少的元素,没有重复无检查?



Ruby样式:如何检查嵌套散列元素是否存在

解决方案

在我们的例子中,由于 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, NoMethodErrors 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屋!

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