红宝石排序偶数和奇数问题



我正在学习Ruby,刚开始排序。尝试像这样对数组进行排序:[1,3,5,2,4,6],我真的不明白代码有什么问题。任何帮助将不胜感激!

[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

首先,让我们修复你的缩进(并转换为标准的Ruby社区编码风格),以便我们可以更好地了解发生了什么:

[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

现在,问题变得很明显了:你的第一个条件表达式的计算结果是0-11,但对这个值没有做任何事情。该值不存储在变量中,不作为参数传递,不返回。它只是被忽略了。整个表达式是无操作的。

这意味着唯一重要的是:

if (x.odd? && y.odd?) || (x.even? && y.even?)
x <=> y
end 

这将为两个相等的元素返回0,对于两个不相等但都是奇数或两个偶数的元素,-11,对于一个元素是奇数而一个元素是偶数的元素,这将返回nil(sort意味着"这两个元素是不可比的,它们没有定义的相对顺序")。由于sort要求所有元素都具有可比性,因此它将中止。

解决此问题的最简单方法可能是将数组划分为奇数和偶数,分别对它们进行排序,然后将它们连接起来:

[1, 2, 3, 4, 5, 6].partition(&:odd?).map(&:sort).inject(:concat)
#=> [1, 3, 5, 2, 4, 6]

或者反过来做,只是将它们全部排序,然后分区(感谢@Eric Duminil):

[1, 2, 3, 4, 5, 6].sort.partition(&:odd?).inject(:concat)
#=> [1, 3, 5, 2, 4, 6]

这可能是我第一次使用负模:

  • i % -2-1如果i是奇数
  • i % -20,如果i是偶数

因此,先按i % -2排序,然后再按i排序应该达到预期的结果。

如果您希望偶数在奇数之前,则可以按i % 2排序。


[3, 2, 1, 5, 6, 4].sort_by{ |i| [ i % -2, i] }
#=> [1, 3, 5, 2, 4, 6]

感谢@Stefan的最初想法!

最新更新