Cos’è l’operatore Ruby (astronave)?

Cos’è l’operatore Ruby (astronave)? L’operatore è implementato da altre lingue?

Perl era probabilmente la prima lingua ad usarlo. Groovy è un altro linguaggio che lo supporta. Fondamentalmente invece di restituire 1 ( true ) o 0 ( false ) a seconda che gli argomenti siano uguali o non uguali, l’operatore dell’astronave restituirà 1 , 0 o −1 seconda del valore dell’argomento di sinistra relativo all’argomento di destra.

 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 

È utile per l’ordinamento di un array.

Il metodo dell’astronave è utile quando lo definisci nella tua class e includi il modulo Comparable . La tua class ottiene quindi i valori >, < , >=, <=, ==, and between? metodi gratis.

 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.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 # [#, #, #] 

È un operatore di confronto generale. Restituisce un valore -1, 0 o +1 a seconda che il suo ricevitore sia inferiore, uguale o maggiore del suo argomento.

Spiegherò con un semplice esempio

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

    Ruby inizierà a confrontare ogni elemento di entrambi gli array dal lato sinistro. 1 per l’array di sinistra è inferiore a 2 dell’array di destra. Quindi l’array di sinistra è più piccolo dell’array di destra. L’output sarà -1 .

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

    Come sopra, prima confronterà il primo elemento che è uguale allora confronterà il secondo elemento, in questo caso il secondo elemento dell’array sinistro è maggiore quindi l’output è 1 .

Poiché questo operatore riduce i confronti a un’espressione intera, fornisce il modo più generale per ordinare in ordine crescente o decrescente in base a più colonne / attributi.

Ad esempio, se ho una matrice di oggetti posso fare cose del genere:

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

Questo modello di base può essere generalizzato per ordinare per qualsiasi numero di colonne, in ogni permutazione di ascendente / discendente su ciascuna.

Che cos’è <=> (L’operatore ‘Spaceship’)

Secondo la RFC che ha introdotto l’operatore , $ a <=> $ b

  - 0 if $a == $b - -1 if $a < $b - 1 if $a > $b 

  - Return 0 if values on either side are equal - Return 1 if value on the left is greater - Return -1 if the value on the right is greater 

Esempio:

 //Comparing Integers echo 1 <=> 1; //ouputs 0 echo 3 <=> 4; //outputs -1 echo 4 <=> 3; //outputs 1 //String Comparison echo "x" <=> "x"; // 0 echo "x" <=> "y"; //-1 echo "y" <=> "x"; //1 

DI PIÙ:

 // Integers echo 1 <=> 1; // 0 echo 1 <=> 2; // -1 echo 2 <=> 1; // 1 // Floats echo 1.5 <=> 1.5; // 0 echo 1.5 <=> 2.5; // -1 echo 2.5 <=> 1.5; // 1 // Strings echo "a" <=> "a"; // 0 echo "a" <=> "b"; // -1 echo "b" <=> "a"; // 1 echo "a" <=> "aa"; // -1 echo "zz" <=> "aa"; // 1 // Arrays echo [] <=> []; // 0 echo [1, 2, 3] <=> [1, 2, 3]; // 0 echo [1, 2, 3] <=> []; // 1 echo [1, 2, 3] <=> [1, 2, 1]; // 1 echo [1, 2, 3] <=> [1, 2, 4]; // -1 // Objects $a = (object) ["a" => "b"]; $b = (object) ["a" => "b"]; echo $a <=> $b; // 0