简体   繁体   English

Ruby排序偶数和奇数问题

[英]Ruby sorting even and odd numbers issue

I'm learning Ruby and just started with the sorting. 我正在学习Ruby,只是从排序开始。 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. 试图像这样对数组进行排序:[1,3,5,2,4,6]而且我真的不太了解代码的问题。 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: 首先,让我们修复缩进(并转换为标准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

Now, the problem becomes obvious: your first conditional expression evaluates to 0 , -1 , or 1 , but nothing is being done with this value . 现在,问题变得很明显:您的第一个条件表达式的计算结果为0-11 ,但是使用此值不执行任何操作 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. 整个表达式是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. 这将返回0两个元素是相等的, -11为两个元件是不相等的,但两者的奇数或偶数,和nil (其以sort单元“这两个元件都非可比性,它们不具有一定义相对顺序”),其中一个元素为奇数,一个元素为偶数。 Since sort requires all elements to be comparable, it will then abort. 由于sort要求所有元素都具有可比性,因此它将中止。

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 ): 或者反过来做,将它们全部排序, 然后分区( 谢谢@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是奇数, i % -2-1
  • i % -2 is 0 if i is even 如果i是偶数, i % -20

So sorting by i % -2 first and then by i should achieve the desired result. 因此,先按i % -2排序,然后再按i排序即可达到理想的结果。

If you want even numbers before odd numbers, you can sort by i % 2 . 如果要在奇数之前输入偶数,则可以按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! 感谢@Stefan的初衷!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM