web-dev-qa-db-ja.com

Ruby <=>(宇宙船)演算子とは何ですか?

Ruby <=>(宇宙船)演算子とは何ですか?オペレーターは他の言語で実装されていますか?

243
Justin Ethier

Perlはおそらくそれを使用した最初の言語でした。 Groovyはそれをサポートする別の言語です。基本的に、引数が等しいか等しくないかに応じて1true)または0false)を返す代わりに、宇宙船演算子は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

配列の並べ替えに便利です。

324
TonyArra

宇宙船メソッドは、独自のクラスで定義して 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>]
67
steenslag

これは一般的な比較演算子です。受信者が引数より小さい、等しい、または大きいかどうかに応じて、-1、0、+ 1のいずれかを返します。

19
gnovice

簡単な例で説明します

  1. [1,3,2] <=> [2,2,2]

    Rubyは、両方の配列の各要素を左側から比較し始めます。左側の配列の1は、右側の配列の2よりも小さいです。したがって、左の配列は右の配列よりも小さくなります。出力は-1になります。

  2. [2,3,2] <=> [2,2,2]

    上記のように、最初に等しい最初の要素を比較し、次に2番目の要素を比較します。この場合、左の配列の2番目の要素が大きいため、出力は1です。

15
Anil Maurya

この演算子は整数式との比較を減らすため、複数の列/属性に基づいて昇順または降順でソートする最も一般的な方法を提供します。

たとえば、オブジェクトの配列がある場合、次のようなことができます。

# `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

この基本パターンは、各列の昇順/降順の順列で、任意の数の列でソートするように一般化できます。

3
lilole