将方法的proc作为块提供

时间:2010-10-18 15:15:49

标签: ruby codeblocks proc

假设我有以下数组:

arr = [[5, 1], [2, 7]]

我希望找到最小元素,比较元素的第二个元素。由于[5, 1]小于1,因此最小元素为7。我可以使用以下代码:

arr.min {|a,b| a[1] <=> b[1]}

为了计算最大值,我可以这样做:

arr.max {|a,b| a[1] <=> b[1]}

这给了[2, 7]

我一直使用相同的块。我想在某处拥有该块并将其提供给min / max函数。我希望有类似的东西:

blo = lambda {|a,b| a[1] <=> b[1]}
arr.min blo

会起作用,但事实并非如此。我怎么能这样做?

5 个答案:

答案 0 :(得分:24)

使用&运算符将Proc对象转换为块。

arr.min &blo

答案 1 :(得分:14)

@ sepp2k的答案是更普遍的答案,但在你的具体情况下,我只会使用

arr.min_by(&:last)
arr.max_by(&:last)

因为那些很多比所有那些花括号和方括号以及浮动的数组索引更明显。

答案 2 :(得分:3)

如果您需要的只是最小值和最大值,则可以使用Enumerable#minmax方法并同时计算两者:

min, max = arr.minmax {|a,b| a[1] <=> b[1]}
#=> [[5, 1], [2, 7]]
min
#=> [5, 1]
max
#=> [2, 7]

编辑:天啊,我刚注意到还有minmax_by,因此您可以将其与last方法结合使用,并具有:

min, max = arr.minmax_by &:last

答案 3 :(得分:2)

怎么样?

=> [[5, 4], [9, 5], [2, 7]]
>> arr.sort!{|x,y| x[1]<=>y[1] }
=> [[5, 4], [9, 5], [2, 7]]
>> min,max=arr[0],arr[-1]
=> [[5, 4], [2, 7]]

答案 4 :(得分:1)

对这类问题的更通用的解决方案是完全避免嵌套数组并改为使用类。然后,您可以定义&lt; =&gt;该类的运算符,允许您访问Comparable mixin中的所有函数(http://ruby-doc.org/core/classes/Comparable.html),为您提供&lt ;,&lt; =,==,&gt; =,和&gt;运算符和方法'之间?'

这只是一个例子,在现实生活中你会使用描述它们存储内容的类:

class Duo

  include Comparable

  def initialize( a, b )
      @a = a
      @b = b
  end

  def <=>(rhs)
      @b <=> rhs.b
  end

end

如果您有一个Duo对象数组,则可以使用min,max和sort函数,而无需定义比较运算符。所以......

@a = Duo.new( 1, 10 )
@b = Duo.new( 2, 5 )
@c = Duo.new( 3, 1 )

[ @a, @b, @c ].sort

将返回数组[@c,@ b,@ a]

[@a, @b, @c].max

会返回@a

这更像是“Ruby Way”,而不是嵌套数据结构,其逻辑依赖于数组中的位置。一开始需要稍微多做一些工作,但从长远来看,你会发现很多更好。

Ruby是一种非常面向对象的编程语言,为您提供了非常强大的工具。我完全建议您阅读“Ruby编程语言”或“The Ruby Way”这样的书,以便对该语言的强大功能进行适当的概述。