2011-01-07 4 views
25

クラスAは以下のコンパレータがあります。カスタムコンパレータを "ソート"に渡すには?

class A 
    attr_accessor x 

    def my_comparator(a) 
    x**2 <=> (a.x)**2 
    end 
end 

を私は、各項目がクラスAである配列をソートするために、このコンパレータを使用したい:

class B 
    def my_method 
    items.sort!(<how can I pass my_comparator here ?>) 
    end 
end 

にはどうすればsort!my_comparatorを渡す必要がありますか?

+1

文字通り、あなたは 'items.sortを使用することができます! {| x、y | x.my_comparator y} 'ですが、これがクラスのデフォルトのソート動作であれば、Tin Manが以下のように考えるべきです。 – coreyward

答えて

33

<=>あなた自身を定義し、比較可能な含まれています。

class SizeMatters 
    include Comparable 
    attr :str 
    def <=>(anOther) 
    str.size <=> anOther.str.size 
    end 
    def initialize(str) 
    @str = str 
    end 
    def inspect 
    @str 
    end 
end 

s1 = SizeMatters.new("Z") 
s2 = SizeMatters.new("YY") 
s3 = SizeMatters.new("XXX") 
s4 = SizeMatters.new("WWWW") 
s5 = SizeMatters.new("VVVVV") 

s1 < s2      #=> true 
s4.between?(s1, s3)   #=> false 
s4.between?(s3, s5)   #=> true 
[ s3, s2, s5, s4, s1 ].sort #=> [Z, YY, XXX, WWWW, VVVVV] 

あなたが実際に匹敵含める必要はありませんが、あなたは<=>を定義した後にそれを行う場合、あなたは自由のための追加機能を得る:これはComparable docからです。

オブジェクトが<=>をすでに実装している場合は、Enumerable's sortをブロックに使用できます。

編集:いくつかの異なる比較を使用する別の方法は、lambdasを使用することです。これは、新しい1.9.2宣言の構文を使用します。

ascending_sort = ->(a,b) { a <=> b } 
descending_sort = ->(a,b) { b <=> a } 

[1, 3, 2, 4].sort(& ascending_sort) # => [1, 2, 3, 4] 
[1, 3, 2, 4].sort(& descending_sort) # => [4, 3, 2, 1] 

foo = ascending_sort 
[1, 3, 2, 4].sort(& foo) # => [1, 2, 3, 4] 
+1

または、この質問に固有の: 'alias_method:<=>、:my_comparator' – Phrogz

+0

+1。グッドキャッチ@Phrogz、最初はRuby-ishというメソッドを呼び出す方が「<=>」です。 –

+0

私の場合はいくつかのコンパレータがあるので、 '<=>'を 'my_comparator'でオーバーライドしたくありません。 –

16

これらの両方が動作するはずです:

items.sort_by! { |a| (a.x)**2 } 
items.sort! { |a1,a2| a1.my_comparator(a2) } 
+0

これはいいですが、正しいですが、@ theTinManの答えはカスタムクラスの方が優れています。 – Phrogz

+0

これは私が探していた答えでした。 –

5
items.sort!(&:my_comparator) 

を従って、これはベン・アルパートの答えにこの答えを削減ブロック

proc {|x,y| x.my_comparator(y)} 

を返し、内部:my_comparator.to_procを呼び出します。

(しかし、私は、これはクラスの自然ためであれば、あなたの代わりにスズ男の答えを使用する必要があることPhrogzの観測に同意する。)

関連する問題