webentwicklung-frage-antwort-db.com.de

Was ist der Operator Ruby <=> (Raumschiff)?

Was ist das Ruby <=> (Raumschiff) Betreiber? Wird der Operator von anderen Sprachen implementiert?

243
Justin Ethier

Perl war wahrscheinlich die erste Sprache, die es verwendete. Groovy ist eine andere Sprache, die es unterstützt. Grundsätzlich anstatt 1 (true) oder 0 (false) Abhängig davon, ob die Argumente gleich oder ungleich sind, gibt der Raumschiffoperator 1, 0, oder −1 abhängig vom Wert des linken Arguments im Verhältnis zum rechten Argument.

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

Es ist nützlich, um ein Array zu sortieren.

324
TonyArra

Die Raumschiffmethode ist nützlich, wenn Sie sie in Ihrer eigenen Klasse definieren und das Vergleichbares Modul einschließen. Deine Klasse bekommt dann das >, < , >=, <=, ==, and between? Methoden kostenlos.

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

Es ist ein allgemeiner Vergleichsoperator. Es gibt entweder -1, 0 oder +1 zurück, je nachdem, ob sein Empfänger kleiner, gleich oder größer als sein Argument ist.

19
gnovice

Ich werde es mit einem einfachen Beispiel erklären

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

    Ruby vergleicht nun jedes Element beider Arrays von links. 1 Für das linke Array ist kleiner als 2 Für das rechte Array. Daher ist das linke Array kleiner als das rechte Array. Die Ausgabe erfolgt mit -1.

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

    Wie oben, vergleicht es zuerst das erste Element, das gleich ist, und dann das zweite Element. In diesem Fall ist das zweite Element des linken Arrays größer und die Ausgabe ist 1.

15
Anil Maurya

Da dieser Operator Vergleiche auf einen ganzzahligen Ausdruck reduziert, bietet er die allgemeinste Möglichkeit, aufsteigend oder absteigend nach mehreren Spalten/Attributen zu sortieren.

Wenn ich zum Beispiel ein Array von Objekten habe, kann ich Folgendes tun:

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

Dieses Grundmuster kann verallgemeinert werden, um nach einer beliebigen Anzahl von Spalten in einer beliebigen Permutation von aufsteigend/absteigend auf jeder zu sortieren.

3
lilole