Ruby 具有两个参数的块

Ruby 具有两个参数的块,ruby,Ruby,我通过用户Hirolau找到了以下代码: def sum_to_n?(a, n) a.combination(2).find{|x, y| x + y == n} end a = [1, 2, 3, 4, 5] sum_to_n?(a, 9) # => [4, 5] sum_to_n?(a, 11) # => nil 如何知道何时可以将两个参数发送到预定义的方法,如find?我不清楚,因为有时它不起作用。这是重新定义的吗?函数对元素进行迭代,它只接受一个参数,在本例中是一个

我通过用户Hirolau找到了以下代码:

def sum_to_n?(a, n)
  a.combination(2).find{|x, y| x + y == n}
end

a = [1, 2, 3, 4, 5]
sum_to_n?(a, 9)  # => [4, 5]
sum_to_n?(a, 11) # => nil

如何知道何时可以将两个参数发送到预定义的方法,如
find
?我不清楚,因为有时它不起作用。这是重新定义的吗?

函数对元素进行迭代,它只接受一个参数,在本例中是一个块(一个散列包含两个参数):

但是,除非使用分解结构,否则该块对数组只接受一个参数


更新:在这种情况下,它似乎是在分解结构。

如果您查看
Enumerable#find
的文档,您会发现它只接受块的一个参数。之所以可以发送两个,是因为Ruby基于其“并行分配”结构,可以方便地使用块执行此操作:

[[1,2,3], [4,5,6]].each {|x,y,z| puts "#{x}#{y}#{z}"}
# 123
# 456
因此,基本上,每个块都会向块生成一个数组元素,并且由于Ruby块语法允许通过提供参数列表将数组元素“扩展”到它们的组件,所以它是有效的

您可以找到更多使用块参数的技巧

a.组合(2)
产生一个数组,其中每个子数组由2个元素组成。因此:

a = [1,2,3,4]
a.combination(2)
# => [[1, 2], [1, 3], [1, 4], [2, 3], [2, 4], [3, 4]]
因此,您将一个类似
[1,2]
的数组发送到find的块,Ruby执行并行赋值,将1赋值给
x
,将2赋值给
y

另请参见SO问题,它带来了其他强大的并行赋值示例,如以下语句:

a,(b,(c,d)) = [1,[2,[3,4]]]

find
不接受两个参数,而是接受一个参数。示例中的块采用两个参数的原因是因为它使用的是销毁。前面的代码
a.composition(2)
给出了两个元素的数组,并且
find
对其进行迭代。每个元素(由两个元素组成的数组)一次作为其单个参数传递给块。但是,当您写入的参数超过实际值时,Ruby会尝试通过破坏数组来调整参数。该部分:

find{|x, y| x + y == n}
是写作的简写:

find{|(x, y)| x + y == n}

请参阅此答案-为了清楚起见,find接受1个可选参数和一个块。该块包含两个参数。我是hirolau,我赞同这个消息。我相信它是“解构”而不是分解+1用于给出paren替代值。如果是散列,则隐式应用到a,因此与数组相同。是。我必须承认,
composition
方法返回了一个散列,并希望给出一个简单的答案,而不必进行解构之类的工作,但我没有抓住要点。然后,我如何学习“并行赋值”、“分解”以及Ruby“块语法如何允许扩展数组元素”,我的意思是,我读过几本书和在线教程,但从未读过,你能给我一个开始寻找的提示吗?谢谢你的回复。顺便说一句,我没有很好的资源给你。我读过的关于Ruby的最好的书是Paolo Perrotta写的《元编程Ruby》(由实用程序员出版),但我只是检查了一下——它没有提到这些。这是在大多数教程(例如)中解释的并行赋值的一种有用的边缘情况。语言中有些东西即使是有经验的开发人员也会不断学习,阅读的代码越多,掌握的技巧就越多。不过,我绝对推荐那本书。容易阅读,你会从中受益匪浅。
find{|(x, y)| x + y == n}