I'm learning Ruby and just started with the sorting. Trying to sort the array like this: [1,3,5,2,4,6] and I'm don't really understand what is wrong with the code. Any help would be appreciated!
[1,2,3,4,5,6].sort do |x,y|
if x.odd? and y.odd?
0
elsif x.odd?
-1
else
1
end
if (x.odd? && y.odd?) or (x.even? && y.even?)
x <=> y
end
end
First off, let's fix your indentation (and convert to standard Ruby community coding style), so that we can better see what's going on:
[1, 2, 3, 4, 5, 6].sort do |x, y|
if x.odd? && y.odd?
0
elsif x.odd?
-1
else
1
end
if (x.odd? && y.odd?) || (x.even? && y.even?)
x <=> y
end
end
Now, the problem becomes obvious: your first conditional expression evaluates to 0
, -1
, or 1
, but nothing is being done with this value . The value is not stored in a variable, not passed as an argument, not returned. It is simply ignored. The entire expression is a NO-OP.
Which means that the only thing that matters is this:
if (x.odd? && y.odd?) || (x.even? && y.even?)
x <=> y
end
This will return 0
for two elements that are equal, -1
or 1
for two elements that are unequal but both odd or both even, and nil
(which to sort
means "these two elements are un-comparable, they don't have a defined relative ordering") for elements where one element is odd and one is even. Since sort
requires all elements to be comparable, it will then abort.
The easiest way to approach this problem would probably be to partition the array into odds and evens, sort them separately, and then concatenate them:
[1, 2, 3, 4, 5, 6].partition(&:odd?).map(&:sort).inject(:concat)
#=> [1, 3, 5, 2, 4, 6]
Or do it the other way round, just sort them all, and then partition ( Thanks @Eric Duminil ):
[1, 2, 3, 4, 5, 6].sort.partition(&:odd?).inject(:concat)
#=> [1, 3, 5, 2, 4, 6]
It's probably the first time I ever used a negative modulo :
i % -2
is -1
if i
is odd i % -2
is 0
if i
is even So sorting by i % -2
first and then by i
should achieve the desired result.
If you want even numbers before odd numbers, you can sort by i % 2
.
[3, 2, 1, 5, 6, 4].sort_by{ |i| [ i % -2, i] }
#=> [1, 3, 5, 2, 4, 6]
Thanks to @Stefan for his original idea!
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.