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


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

Author: Andrew Marshall, 2009-05-06

6 answers

Perl fue probablemente el primer idioma en usarlo. Groovy es otro lenguaje que lo soporta. Básicamente en lugar de volver 1 (true) o 0 (false) dependiendo de si los argumentos son iguales o desiguales, el operador de la nave espacial regresará 1, 0, o −1 dependiendo del valor del argumento izquierdo relativo al argumento derecho.

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.

 288
Author: TonyArra,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-09-15 14:46:58

El método de nave espacial es útil cuando lo define en su propia clase e incluye el Módulo comparable. Su clase entonces obtiene los métodos >, < , >=, <=, ==, and between? 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
    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>]
 57
Author: steenslag,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-01-15 21:43:55

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.

 19
Author: gnovice,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-05-06 01:31:08

Voy a explicar con un simple ejemplo

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

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

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

    Como arriba, primero comparará el primer elemento que son iguales, luego comparará el segundo elemento, en este caso el segundo elemento de la matriz izquierda es mayor, por lo tanto, la salida es 1.

 15
Author: Anil Maurya,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-06-29 16:29:10

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

Por ejemplo, si tengo una matriz 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 se puede generalizar para ordenar por cualquier número de columnas, en cualquier permutación de ascendente/descendente en cada una.

 0
Author: lilole,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-04-11 23:49:37

Qué es <=> (El Operador de la 'Nave Espacial')

De acuerdo con el RFC que introdujo el operador , a a <=> b 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
 -1
Author: RïshïKêsh Kümar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-06-27 08:29:16