首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用Ruby2.3中引入的Array#dig和Hash#dig?

如何使用Ruby2.3中引入的Array#dig和Hash#dig?
EN

Stack Overflow用户
提问于 2015-12-18 00:18:13
回答 3查看 40.4K关注 0票数 52

Ruby2.3在ArrayHash上引入了一种名为dig的新方法。我在博客文章中看到的关于新版本的例子是人为的和复杂的:

代码语言:javascript
复制
# 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样式:如何检查嵌套散列元素是否存在

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-12-18 04:12:28

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

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

让我们以你为例。以下内容如下:

代码语言:javascript
复制
user.dig(:user, :address, :street1)

不等同于

代码语言:javascript
复制
user[:user][:address][:street1]

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

相反,它相当于以下成语,即当前的成语:

代码语言:javascript
复制
user[:user] && user[:user][:address] && user[:user][:address][:street1]

请注意,将在其他地方创建的符号列表传递到Hash#dig中是非常简单的,而从这样的列表重新创建后一个构造则不是很简单。Hash#dig允许您轻松地进行动态访问,而不必担心nil引用。

显然,Hash#dig也要短得多。

需要注意的一点是,如果任何键被证明是正确的,Hash#dig本身就会返回nil,这会导致相同的错误类别,因此提供合理的缺省值可能是个好主意。(这种提供总是响应所需方法的对象的方法称为空对象模式。)

同样,在您的示例中,一个空字符串或类似于"N/A“的东西,取决于什么是有意义的:

代码语言:javascript
复制
user.dig(:user, :address, :street1) || ""
票数 82
EN

Stack Overflow用户

发布于 2015-12-18 00:26:42

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

代码语言:javascript
复制
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
票数 11
EN

Stack Overflow用户

发布于 2019-01-09 01:19:08

它对于深入嵌套的散列/数组非常有用,例如,这可能就是从API调用中得到的结果。

理论上,它节省了大量的代码,否则将在每个级别上检查是否存在另一个级别,否则您将面临持续错误的风险。实际上,您可能仍然需要大量这样的代码,因为在某些情况下,dig仍然会创建错误(例如,如果链中有任何东西是无键对象)。

正是由于这个原因,您的问题才是真正有效的-- dig还没有看到我们可能预期的用法。这里对此进行了注释,例如:为什么没人提起挖洞

要使dig避免这些错误,请尝试KeyDial gem,我编写它是为了包装dig,并在出现错误时强制它返回0/default。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34346653

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档