ruby operators comparison-operators spaceship-operator

¿Qué es el operador Ruby<=>(nave espacial)?



operators comparison-operators (6)

¿Qué es <=> (el operador ''Spaceship'')

De acuerdo con el RFC que introdujo al operador , $ 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

Ejemplo:

//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

MÁS:

// 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

¿Qué es el operador Ruby <=> (nave espacial)? ¿El operador está implementado por otros idiomas?


Dado que este operador reduce las comparaciones a una expresión entera, proporciona la manera más general de ordenar ascendente o descendente en función de múltiples columnas / atributos.

Por ejemplo, si tengo una variedad de objetos, puedo hacer cosas como esta:

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

Este patrón básico puede generalizarse para ordenarse por cualquier número de columnas, en cualquier permutación de ascendente / descendente en cada una.


El método de la nave espacial es útil cuando lo define en su propia clase e incluye el módulo Comparable . Entonces tu clase obtiene el >, < , >=, <=, ==, and between? Métodos de forma gratuita.

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>]


Es un operador de comparación general. Devuelve un -1, 0 o +1 dependiendo de si su receptor es menor, igual o mayor que su argumento.


Perl fue probablemente el primer idioma para usarlo. Groovy es otro lenguaje que lo soporta. Básicamente, en lugar de devolver 1 ( true ) o 0 ( false ) dependiendo de si los argumentos son iguales o desiguales, el operador de la nave espacial devolverá 1 , 0 o −1 dependiendo del valor del argumento de la izquierda en relación con el argumento de la derecha.

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 útil para ordenar una matriz.


Te explicaré con un simple ejemplo.

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

    Ruby comenzará a comparar cada elemento de ambas matrices desde el lado izquierdo. 1 para la matriz izquierda es más pequeño que 2 de la matriz derecha. Por lo tanto, la matriz izquierda es más pequeña que la derecha. La salida será -1 .

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

    Como arriba, primero comparará el primer elemento que sea igual a él, luego comparará el segundo elemento, en este caso, el segundo elemento de la matriz izquierda es mayor, por lo que la salida es 1 .