ruby 2.3在ArrayHash上引入了一个新的方法,称为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解决的:
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

最佳答案

在我们的例子中,由于引用而导致的NoMethodErrors是我们在生产环境中看到的最常见的错误。
新的nil允许您在访问嵌套元素时省略Hash#dig检查由于散列最适合用于数据结构未知或不稳定的情况,因此获得官方支持非常有意义。
让我们以你为例。以下内容:

user.dig(:user, :address, :street1)

不等于:
user[:user][:address][:street1]

niluser[:user]user[:user][:address]的情况下,这将导致运行时错误。
相反,它相当于下面这个成语:
user[:user] && user[:user][:address] && user[:user][:address][:street1]

请注意,将在其他地方创建的符号列表传递到nil中是很简单的,而从这样的列表中重新创建后一个构造则不是很简单。Hash#dig允许您轻松地进行动态访问,而无需担心Hash#dig引用。
显然nil也要短得多。
需要注意的一点是,如果有任何键被证明是,那么Hash#dig本身就会返回Hash#dig,这可能会导致同一类错误,因此最好提供一个合理的默认值。(这种提供始终响应所需方法的对象的方法称为Null Object Pattern
同样,在您的示例中,空字符串或类似“N/A”的内容取决于什么是有意义的:
user.dig(:user, :address, :street1) || ""

08-24 23:31