将 proc 作为块提供给方法

发布于 2024-09-27 19:06:51 字数 515 浏览 4 评论 0原文

假设我有以下数组:

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]

我一直使用同一个块。我想将该块放在某处并将其提供给最小/最大函数。我希望这样的事情:

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

会起作用,但没有。我知道如何做到这一点吗?

Let's say I have the following array:

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

and I want to find the minimum element, comparing the second element of the elements. The minimum element will be [5, 1] since 1 is less than 7. I can use the following code:

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

For calculating the maximum, I can do the same:

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

That gives [2, 7].

I use the same block all the time. I would like to have that block somewhere and provide it to the min/max function. I hoped something like:

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

would work, but it didn't. Any idea on how I can do this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

海之角 2024-10-04 19:06:52

这个怎么样?

=> [[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]]

how about this?

=> [[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]]
猫九 2024-10-04 19:06:52

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

这只是一个示例,在现实生活中,您将使用描述其存储内容的类:

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》之类的书,以正确了解该语言的强大功能。

A more general solution to problems like this is to avoid nested arrays entirely and use a class instead. You can then define the <=> operator for that class, giving you access to all the functions in the Comparable mixin (http://ruby-doc.org/core/classes/Comparable.html) gives you the <, <=, ==, >=, and > operators and the method 'between?'

This is just an example, in real life you would use classes that describe what they store:

class Duo

  include Comparable

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

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

end

If you have an array of Duo object you can then use the min, max, and sort functions without having to define the comparison operator. So...

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

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

would return the array [ @c, @b, @a ]

And

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

would return @a

This is much more the 'Ruby Way' than nested data-structures with logic that relies on positions in arrays. It takes slightly more work at the start, but you'll find it much better in the long run.

Ruby is a very object oriented programming language and provides very powerful tools for you to use. I thoroughly recommend reading a book like "The Ruby Programming Language" or "The Ruby Way" to get a proper overview of the power of the language.

倾`听者〃 2024-10-04 19:06:51

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

arr.min &blo

Use the & operator to turn a Proc object into a block.

arr.min &blo
趴在窗边数星星i 2024-10-04 19:06:51

@sepp2k 的答案是更一般的答案,但在您的具体情况下,我只会使用,

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

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

@sepp2k's answer is the more general one, but in your specific case, I would just use

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

since that is much more obvious than all those curly braces and square brackets and array indices floating around.

冷…雨湿花 2024-10-04 19:06:51

如果您需要的只是最小值和最大值,您可以使用 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

If all that you need is minimum and maximum, you might use Enumerable#minmax method and calculate both at once:

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

Edit: Hell, I just noticed there is also minmax_by, so you can combine it with last method, and have:

min, max = arr.minmax_by &:last
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文