Ruby <=>
(宇宙船)演算子とは何ですか?オペレーターは他の言語で実装されていますか?
Perlはおそらくそれを使用した最初の言語でした。 Groovyはそれをサポートする別の言語です。基本的に、引数が等しいか等しくないかに応じて1
(true
)または0
(false
)を返す代わりに、宇宙船演算子は1
を返します。 0
、または−1
は、右引数に対する左引数の値に応じて異なります。
a <=> b :=
if a < b then return -1
if a = b then return 0
if a > b then return 1
if a and b are not comparable then return nil
配列の並べ替えに便利です。
宇宙船メソッドは、独自のクラスで定義して Comparableモジュール を含めると便利です。その後、クラスは>, < , >=, <=, ==, and between?
メソッドを無料で取得します。
class Card
include Comparable
attr_reader :value
def initialize(value)
@value = value
end
def <=> (other) #1 if self>other; 0 if self==other; -1 if self<other
self.value <=> other.value
end
end
a = Card.new(7)
b = Card.new(10)
c = Card.new(8)
puts a > b # false
puts c.between?(a,b) # true
# Array#sort uses <=> :
p [a,b,c].sort # [#<Card:0x0000000242d298 @value=7>, #<Card:0x0000000242d248 @value=8>, #<Card:0x0000000242d270 @value=10>]
これは一般的な比較演算子です。受信者が引数より小さい、等しい、または大きいかどうかに応じて、-1、0、+ 1のいずれかを返します。
簡単な例で説明します
[1,3,2] <=> [2,2,2]
Rubyは、両方の配列の各要素を左側から比較し始めます。左側の配列の1
は、右側の配列の2
よりも小さいです。したがって、左の配列は右の配列よりも小さくなります。出力は-1
になります。
[2,3,2] <=> [2,2,2]
上記のように、最初に等しい最初の要素を比較し、次に2番目の要素を比較します。この場合、左の配列の2番目の要素が大きいため、出力は1
です。
この演算子は整数式との比較を減らすため、複数の列/属性に基づいて昇順または降順でソートする最も一般的な方法を提供します。
たとえば、オブジェクトの配列がある場合、次のようなことができます。
# `sort!` modifies array in place, avoids duplicating if it's large...
# Sort by Zip code, ascending
my_objects.sort! { |a, b| a.Zip <=> b.Zip }
# Sort by Zip code, descending
my_objects.sort! { |a, b| b.Zip <=> a.Zip }
# ...same as...
my_objects.sort! { |a, b| -1 * (a.Zip <=> b.Zip) }
# Sort by last name, then first
my_objects.sort! { |a, b| 2 * (a.last <=> b.last) + (a.first <=> b.first) }
# Sort by Zip, then age descending, then last name, then first
my_objects.sort! do |a, b|
4 * (a.Zip <=> b.Zip) +
-3 * (a.age <=> b.age) +
2 * (a.last <=> b.last) +
(a.first <=> b.first)
end
この基本パターンは、各列の昇順/降順の順列で、任意の数の列でソートするように一般化できます。