Dig 方法¶ ↑
Ruby 的 dig
方法对于访问嵌套数据结构非常有用。
考虑以下数据
item = { id: "0001", type: "donut", name: "Cake", ppu: 0.55, batters: { batter: [ {id: "1001", type: "Regular"}, {id: "1002", type: "Chocolate"}, {id: "1003", type: "Blueberry"}, {id: "1004", type: "Devil's Food"} ] }, topping: [ {id: "5001", type: "None"}, {id: "5002", type: "Glazed"}, {id: "5005", type: "Sugar"}, {id: "5007", type: "Powdered Sugar"}, {id: "5006", type: "Chocolate with Sprinkles"}, {id: "5003", type: "Chocolate"}, {id: "5004", type: "Maple"} ] }
如果没有 dig
方法,你可以写
item[:batters][:batter][1][:type] # => "Chocolate"
如果有 dig
方法,你可以写
item.dig(:batters, :batter, 1, :type) # => "Chocolate"
如果没有 dig
方法,你可以写(错误地引发 NoMethodError (undefined method `[]' for nil:NilClass)
)
item[:batters][:BATTER][1][:type]
如果有 dig
方法,你可以写(仍然错误,但避免了异常)
item.dig(:batters, :BATTER, 1, :type) # => nil
为什么 dig
更好?¶ ↑
-
它有更少的语法元素(出错的可能性更小)。
-
它读起来更好。
-
如果未找到项目,它不会引发异常。
dig
如何工作?¶ ↑
调用顺序为
obj.dig(*identifiers)
identifiers
定义嵌套数据结构中的“路径”
-
对于
identifiers
中的每个标识符,使用该标识符调用接收器上的方法 #dig。 -
第一个接收器是
self
。 -
每个连续的接收器都是由对
dig
的前一次调用返回的值。 -
最后返回的值是对
dig
的最后一次调用返回的值。
如果任何接收器未响应 #dig,则 dig
方法会引发异常
h = { foo: 1 } # Raises TypeError (Integer does not have #dig method): h.dig(:foo, :bar)
还有什么?¶ ↑
上述结构具有 Hash 对象和 Array 对象,它们都具有实例方法 dig
。
总共有六个内置 Ruby 类具有方法 dig
,三个在核心类中,三个在标准库中。
在核心
-
Array#dig
:第一个参数是整数索引。 -
Hash#dig
:第一个参数是键。 -
Struct#dig
:第一个参数是键。
在标准库
-
OpenStruct#dig
:第一个参数是字符串名称。 -
CSV::Table#dig
:第一个参数是整数索引或字符串标题。 -
CSV::Row#dig
:第一个参数是整数索引或字符串标题。