what makes an operator <=> in the block min? [duplicate] - ruby

This question already has answers here:
What is the Ruby <=> (spaceship) operator?
(6 answers)
Closed 6 years ago.
Have following example of code:
%w{ Ruby C APL Perl Smalltalk}.min {|a,b| a.size <=> b.size}
return "C"
Can you explain me why "C"? What makes an operator "<=>" ?

The Spaceship operator returns -1 if the left is less than the right, 0 if they are equal, and 1 if the left is greater than the right.
In this case, you're comparing the length of each word in the array and returning the shortest word. If you removed .size from the variable in the block, it would instead return the first word that occurs alphabetically (i.e. 'APL').
What is the Ruby <=> (spaceship) operator?

Related

What's the proper way to use the <=> operator in Ruby? [duplicate]

This question already has answers here:
What is the Ruby <=> (spaceship) operator?
(6 answers)
Closed 4 years ago.
I don't quite understand how this works. I guess a large part of it is because I'm used to C and its low-level data structures, and programming at a higher level of abstraction takes some getting used to. Anyway, I was reading The Ruby Programming Language, and I came to the section about ranges and how you can use the <=> operator as sort of a shorthand for what in C you would have to implement as a sequence of if-else statements. It returns either -1, 0, or 1 depending on the results of the comparison. I decided to try it out with the following statement:
range = 1..100
r = (100 <=> range)
print( r )
The result is an empty string. So my question is, how does this operator work; what data type does it return (I assume the return value is an integer type but I can't say for sure); and finally what is the proper way to use it? Thanks for your time, and sorry if this was already answered (I didn't see it in the listing).
The <=> operator is meant to compare two values that can be compared directly, as in strings to strings or numbers to numbers. It can't magically compare two different things, Ruby doesn't convert for you like that.
As such you need to use it in the right context:
1 <=> 2
# => -1
2 <=> 1
# => 1
1 <=> 1
# => 0
When the two things can't be compared you get nil. Note that this is different from "empty string":
1 <=> '1'
# => nil
That means "invalid comparison". The <=> operator is being nice here because in other situations you get an exception:
1 < '1'
# => ArgumentError: comparison of Integer with String failed
You can also use this operator to make your own Comparable compatible class:
class Ordered
include Comparable
attr_reader :sequence
def initialize(sequence)
#sequence = sequence
end
def <=>(other)
self.sequence <=> other.sequence
end
end
Then you can do this:
a = Ordered.new(10)
b = Ordered.new(2)
[ a, b ].sort
# => [#<Ordered:0x00007ff1c6822b60 #sequence=2>, #<Ordered:0x00007ff1c6822b88 #sequence=10>]
Where those come out in order. The <=> implementation handles how these are sorted, and you can finesse that depending on how complex your sorting rules are.
Using the return values -1, 0, and 1 only as labels describing different states, you can write a condition that depends on the order between two numbers:
case a <=> b
when -1 then # a is smaller than b. Do something accordingly
when 0 then # a equals b. Do something accordingly
when 1 then # a is larger than b. Do something accordingly
end
Or, a use case where you can make use of the values -1, 0, and 1, is when you want to get the (non-negative) difference between two numbers a and b without using the abs method. The following:
(a - b) * (a <=> b)
will give the difference.
Add to the other answers this snippet: The "spaceship operator" returns -1, 0, or 1 so you can use it when comparing items in a .sort call:
events.sort {|x, y| y.event_datetime <=> x.event_datetime}
0 means the two items are the same, 1 means they are different but in the correct sort order, and -1 means they are out of order. The above example reverses x and y to sort into descending order.
In C, the function strcmp() has roughly the same behavior, to fit with qsort(), with the same semantics.

Ruby Syntax Explanation [duplicate]

This question already has answers here:
How does this block work for Integer times method?
(2 answers)
Closed 6 years ago.
I was reading through the documentation for Enumerator and I ran across this example:
fib = Enumerator.new do |y|
a = b = 1
loop do
y << a
a, b = b, a + b
end
end
Everything makes sense to me except for this line: a, b = b, a + b. Could somebody please explain what's happening?
It's a parallel assignment pattern which you can see in many languages including ruby
probably you will find this helpful
Parallel Assignment operator in Ruby

finding median in Ruby [duplicate]

This question already has answers here:
Find the median of an array
(4 answers)
Closed 9 years ago.
input: A list of numbers from the keyboard.
output: The median of the input numbers
I need the whole code
def median(array)
array.sort!
if (array.length % 2==1 )
return array[array.length/2.0]
else
return (array[array.length/2] + array[(array.length/2)-1])/2.0
end
end
How can I enter list from keyboard and the find the median?
Assuming you want numbers separated by spaced on a single input line (i.e. 1 5 56 6 75), add the following to your script:
input_array = gets.chomp.split(" ")
Then pass input_array to your median method
Update: Note that input_array will be an array of strings, so you'll need to convert values to integers. Here's a good example on doing so.

Ruby single line ternary in function, is returning boolean [duplicate]

This question already has answers here:
Ternary expression with "defined?" returns "expression" instead of value?
(3 answers)
Closed 9 years ago.
def fib(n)
[0,1].include? n ? n : (fib(n-1) + fib(n-2))
end
fib 5 => false
Why is this? Since it works when broken out into standard if then else.
Operator precedence. You're effectively doing this:
[0, 1].include? (n ? n : fib...)
That is, the result of n ? n : (fib(n-1) + fib(n-2)) is found, and that is passed to include?.
Use parenthesis to force the order of evaluation you intend:
[0, 1].include?(n) ? n : (f(n - 1) + fib(n - 2))

Operator <=> in Ruby [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What is the Ruby <=> (spaceship) operator?
I saw a code and an operator I'm unfamiliar with
#array << {:suffix=> substring, :index => i}
#array.sort! { |x,y| x[:suffix] <=> y[:suffix]}
I can't do google on it. What does <=> do?
This is the spaceship operator, it was borrowed from Perl. It is commonly used for sorting, because it returns -1 if left operand is less than right operand, 1 if right operand is greater than the left and returns 0 otherwise.
1 <=> 2 # => -1
2 <=> 1 # => 1
1 <=> 1 # => 0
It does comparison defined for the particular class. If it is the case that ... < ... is true, it returns -1, if ... == ... is true, then 0, and if ... > ... is true, then 1.
It's called the spaceship operator.
For the core numeric and string classes, it's a comparison operator that returns -1, 0, or 1.
In theory, a class can define any operator to do anything it wants, but this will be the method that is used when sorting. It may make sense to define <=> for an arbitrary application class if that class will ever need to be ordered.

Resources