在ruby中有没有办法同时将块的参数绑定到本地以及解构它?
谷歌搜索没有找到任何东西,在IRB中玩游戏毫无结果,但我想我回忆起类似于以下内容的功能:
>> [[1, 2], [3, 4]].map{|x@(y, z)| [x, y, z]}
=> [[[1, 2], 1, 2], [[3, 4], 3, 4]]
其中x
捕获迭代对象的每个顶级元素(在本例中为第一个[1, 2]
,然后[3, 4]
)和y
以及z
捕获x
内部的对象的子元素(1
然后3
和2
然后4
。
我刚刚想到,我投射到Ruby中的功能实际上来自Haskell:What does the "@" symbol mean in reference to lists in Haskell?
但是,还有一种优雅的方法可以在Ruby中实现相同的目标吗?
答案 0 :(得分:4)
我想要一个将[[1,2],[3,4]]分配给x,[1,2]到y和[3,4]到z
的解决方案
这个怎么样:
irb(main):001:0> y, z = x = [[1, 2], [3, 4]]
=> [[1, 2], [3, 4]]
irb(main):002:0> y
=> [1, 2]
irb(main):003:0> z
=> [3, 4]
irb(main):004:0> x
=> [[1, 2], [3, 4]]
更新(让我们把它放到一个区块中)
这对你来说是这样的:
[[1, 2], [3, 4]].tap do |arr|
y, z = x = arr
p x # => [[1, 2], [3, 4]]
p y # => [1, 2]
p z # => [3, 4]
end
答案 1 :(得分:1)
这个怎么样?:
2.3.0 :003 > x, (y, z) = [[1, 2], [3, 4]]
=> [[1, 2], [3, 4]]
2.3.0 :004 > x
=> [1, 2]
2.3.0 :005 > y
=> 3
2.3.0 :006 > z
=> 4
或者这个?:
2.3.0 :007 > x = [[1, 2], [3, 4]]
=> [[1, 2], [3, 4]]
2.3.0 :008 > y, z = x
=> [[1, 2], [3, 4]]
2.3.0 :009 > y
=> [1, 2]
2.3.0 :010 > z
=> [3, 4]
或者,如果你真的想将它们全部合并到一个陈述中(尽管可能不太清楚):
2.3.0 :011 > y, z = (x = [[1, 2], [3, 4]])
=> [[1, 2], [3, 4]]
2.3.0 :012 > x
=> [[1, 2], [3, 4]]
2.3.0 :013 > y
=> [1, 2]
2.3.0 :014 > z
=> [3, 4]
我可能不明白你想做什么;我不认为map
是您想要的,因为它对输入数组中的所有元素执行相同的操作,并且您正在混合整个数组和数组元素操作。这是可以做你想做的事情的方法,我不知道......
2.3.0 :017 > def f(x)
2.3.0 :018?> y, z = x
2.3.0 :019?> yield x, y, z
2.3.0 :020?> end
=> :f
2.3.0 :030 > f([[1, 2], [3, 4]]) { |x, y, z| p x; p y; p z }
[[1, 2], [3, 4]]
[1, 2]
[3, 4]
答案 2 :(得分:1)
您可以创建一个自定义数组方法来完成工作:
class NestedArray < Array
def each(&blk)
super { |array| blk.call(array, *array) }
end
def map(&blk)
super { |array| blk.call(array, *array) }
end
end
用法:
nested_array = NestedArray.new([[1,2],[3,4]])
nested_array.each do |x, y, z|
puts "#{x}#{y}#{z}"
end
# result:
# [1, 2]12
# [3, 4]34
附加参数是可选的,即你仍然可以写
nested_array.each { |x| puts x }
即使您选择不使用y
和z
参数,它仍然有效。