What is the Ruby <=>
(spaceship) operator? Is the operator implemented by any other languages?
问题:
回答1:
Perl was likely the first language to use it. Groovy is another language that supports it. Basically instead of returning 1
(true
) or 0
(false
) depending on whether the arguments are equal or unequal, the spaceship operator will return 1
, 0
, or −1
depending on the value of the left argument relative to the right 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
It\'s useful for sorting an array.
回答2:
The spaceship method is useful when you define it in your own class and include the Comparable module. Your class then gets the >, < , >=, <=, ==, and between?
methods for free.
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>]
回答3:
It\'s a general comparison operator. It returns either a -1, 0, or +1 depending on whether its receiver is less than, equal to, or greater than its argument.
回答4:
I will explain with simple example
[1,3,2] <=> [2,2,2]
Ruby will start comparing each element of both array from left hand side.
1
for left array is smaller than2
of right array. Hence left array is smaller than right array. Output will be-1
.[2,3,2] <=> [2,2,2]
As above it will first compare first element which are equal then it will compare second element, in this case second element of left array is greater hence output is
1
.
回答5:
Since this operator reduces comparisons to an integer expression, it provides the most general purpose way to sort ascending or descending based on multiple columns/attributes.
For example, if I have an array of objects I can do things like this:
# `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
This basic pattern can be generalized to sort by any number of columns, in any permutation of ascending/descending on each.
回答6:
What is
<=>
( The \'Spaceship\' Operator )
According to the RFC that introduced the operator, $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
Example:
//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
MORE:
// 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