是否可以单独声明传递到注入方法块中的数组元素的块参数?

Is it possible to separately declare block parameters of an array element which is passed into a block for the inject method?

这是我现在正在做的目前有效的,但我觉得有点缺乏语法糖...

f = RGeo::Geos.factory
coords = [ [1,1], [2,2], [1,3] ]
points = coords.inject([]) {|points, coord| points << f.point(coord[0], coord[1]); points }
#=> [#<RGeo::Geos::CAPIPointImpl:0x3fff0950a508 "POINT (1.0 1.0)">, #<RGeo::Geos::CAPIPointImpl:0x3fff0950a47c "POINT (2.0 2.0)">, #<RGeo::Geos::CAPIPointImpl:0x3fff0950a454 "POINT (1.0 3.0)">] 

这是我想做的事情:

points = coords.inject([]) {|points, x, y| points << f.point(x,y); points }
#=> [nil, nil, nil]

现在返回一个包含三个 nil 值的数组。是否可以像使用 each 方法那样分别声明传递到注入块中的元素的数组值?

旁注: 为第一个注入块参数("result" 变量)和等号左侧的变量使用相同的变量名是安全的,对吧?我想是的,因为这只是一个典型的递归案例。如果您有其他感受或知道,请发表评论。

这样做就可以了:

points = coords.inject([]) {|points, (x, y)| points << f.point(x,y); points }

这通常适用于任何区块;如果其中一个块参数是 n 个元素的数组,您可以使用 n 个带括号的参数名称捕获这些元素。如果在括号中使用超过 n 个参数名称,则额外的将为 nil:

[[1,2,3],[4,5]].map {|(a,b,c)| "#{a}+#{b}+#{c.inspect}" } #=> ["1+2+3", "4+5+nil"]

如果您使用的参数名称太少,剩余部分将被丢弃:

[[1,2,3],[4,5]].map {|(a,b)| "#{a}+#{b}" } #=> ["1+2", "4+5"]

您可以使用 splat 运算符来捕获余数,就像使用常规参数一样:

[[1,2,3],[4,5]].map {|(a,*b)| "#{a}+#{b}" } #=> ["1+[2, 3]", "4+[5]"]

你甚至可以嵌套:

[[1,2,[3,4]],[5,6,[7,8]]].map {|(a,b,(c,d))| a+b+c+d } #=> [10, 26]

请注意,嵌套它很快就会造成混淆,因此请谨慎使用。

另请注意,严格来说,这些外括号在上述示例中并不是必需的,但当仅从数组中获取一个参数时,它们会改变行为:

# Makes no difference
[[1,2,3],[4,5,6]].map {| a,b,c | "#{a}+#{b}+#{c}" } #=> ["1+2+3", "4+5+6"]
[[1,2,3],[4,5,6]].map {|(a,b,c)| "#{a}+#{b}+#{c}" } #=> ["1+2+3", "4+5+6"]

# Makes a big difference
[[1,2,3],[4,5,6]].map {| a | a } #=> [[1, 2, 3], [4, 5, 6]]
[[1,2,3],[4,5,6]].map {|(a)| a } #=> [1, 4]