2010-10-18 25 views
10

比方说,我有以下阵列:提供一个进程的方法作为一个块

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 

会工作,但它没有。有关我如何做到这一点的任何想法?

回答

23

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

arr.min &blo 
+2

唯一一个,仔细阅读问题。 – Nakilon 2010-10-18 23:22:12

+0

这正是我所寻找的。非常感谢答复! – 2010-10-19 11:22:36

+0

@Cristobal也许你应该“接受”你满意的答案。它向其他用户表明该问题已被回答并被接受。 – 2010-12-23 11:43:09

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]] 
13

@ sepp2k的回答是更普遍的一个,但在特定情况下,我只想用

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

,因为这是超过所有这些花括号和方括号和明显数组指数浮动。

+0

这一个也适用;) – 2010-10-19 11:24:35

+0

这就是我正在寻找的,所以你可以做'line_items.max_by(&:quantity)'例如。非常感谢 – Dorian 2014-03-24 15:38:57

1

这样的问题的更一般的解决方案是完全避免嵌套数组,并使用类来代替。然后,您可以为该类定义< =>运算符,使您可以访问Comparable mixin中的所有函数(http://ruby-doc.org/core/classes/Comparable.html),为您提供<,< = ,==,> =和>运算符以及方法'between?'

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

class Duo 

    include Comparable 

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

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

end 

如果你有双核的数组对象,那么你可以使用最小,最大和排序功能而不必定义比较运算符。所以......

@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是一种非常面向对象的编程语言,它提供了非常强大的工具供您使用。我完全推荐阅读一本像“The Ruby Programming Language”或“The Ruby Way”这样的书籍,以便正确地了解该语言的功能。

+0

'Duo'这个名称并不表示它会按最后一个元素排序。如果其他人创建了一个由项目的第一个元素排序的Duo,导致两个不同的Duo? – 2010-10-18 22:18:03

+0

那么在你编写的任何代码中总是会出现问题,如果你创建了一个类并且别人也修改了它,那么你就有问题了。但这不是不做的理由。当然这只是一个例子。在现实生活中,你会有一个更具描述性的类名,它实际上描述了存储的内容,而不仅仅是一个通用的两件商店。 – 2010-10-18 22:40:14

+0

嗨,非常感谢您的回复。我非常喜欢它,并且我同意你的观点,从长远来看有时候会更好。然而,在这个场合对于我来说,通过这个街区更快。 – 2010-10-19 11:27:01

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 
相关问题