绑定和解构阻止参数

时间:2016-06-18 05:41:25

标签: ruby

在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然后32然后4

修改

我刚刚想到,我投射到Ruby中的功能实际上来自Haskell:What does the "@" symbol mean in reference to lists in Haskell?

但是,还有一种优雅的方法可以在Ruby中实现相同的目标吗?

3 个答案:

答案 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 }

即使您选择不使用yz参数,它仍然有效。