Ruby2.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解决的。
发布于 2015-12-18 04:12:28
在我们的例子中,由于NoMethodError引用而产生的nil是我们在生产环境中看到的最常见的错误。
新的Hash#dig允许您在访问嵌套元素时省略nil检查。由于哈希最好用于数据结构未知或不稳定的情况下,因此官方对此的支持非常有意义。
让我们以你为例。以下内容如下:
user.dig(:user, :address, :street1)不等同于:
user[:user][:address][:street1]在user[:user]或user[:user][:address]为nil的情况下,这将导致运行时错误。
相反,它相当于以下成语,即当前的成语:
user[:user] && user[:user][:address] && user[:user][:address][:street1]请注意,将在其他地方创建的符号列表传递到Hash#dig中是非常简单的,而从这样的列表重新创建后一个构造则不是很简单。Hash#dig允许您轻松地进行动态访问,而不必担心nil引用。
显然,Hash#dig也要短得多。
需要注意的一点是,如果任何键被证明是正确的,Hash#dig本身就会返回nil,这会导致相同的错误类别,因此提供合理的缺省值可能是个好主意。(这种提供总是响应所需方法的对象的方法称为空对象模式。)
同样,在您的示例中,一个空字符串或类似于"N/A“的东西,取决于什么是有意义的:
user.dig(:user, :address, :street1) || ""发布于 2015-12-18 00:26:42
一种方法是结合splat操作符从一些未知的文档模型中读取。
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发布于 2019-01-09 01:19:08
它对于深入嵌套的散列/数组非常有用,例如,这可能就是从API调用中得到的结果。
理论上,它节省了大量的代码,否则将在每个级别上检查是否存在另一个级别,否则您将面临持续错误的风险。实际上,您可能仍然需要大量这样的代码,因为在某些情况下,dig仍然会创建错误(例如,如果链中有任何东西是无键对象)。
正是由于这个原因,您的问题才是真正有效的-- dig还没有看到我们可能预期的用法。这里对此进行了注释,例如:为什么没人提起挖洞。
要使dig避免这些错误,请尝试KeyDial gem,我编写它是为了包装dig,并在出现错误时强制它返回0/default。
https://stackoverflow.com/questions/34346653
复制相似问题