Ruby排序偶数和奇数问题

时间:2017-03-21 09:52:41

标签: arrays ruby sorting if-statement

我正在学习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

2 个答案:

答案 0 :(得分:4)

首先,让我们修复你的缩进(并转换为标准的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,但没有使用此值进行任何操作 。该值不存储在变量中,不作为参数传递,也不返回。它完全被忽略了。整个表达式都是NO-OP。

这意味着唯一重要的是:

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

对于两个相等,0-1的元素,对于两个不相等且奇数或两者均为偶数的元素,1将返回nil to sort表示“这两个元素无法比较,它们没有定义的相对排序”)对于一个元素是奇数而一个是偶数的元素。由于sort要求所有元素都具有可比性,因此它将中止。

解决这个问题的最简单方法可能是将数组分为几率和均值,分别对它们进行排序,然后将它们连接起来:

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

或者反之亦然,只需对它们进行排序,然后分区(Thanks @Eric Duminil):

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

答案 1 :(得分:1)

这可能是我第一次使用否定modulo

    如果i % -2为奇数,
  • -1i
  • 如果i % -2是,则
  • 0i

首先按i % -2排序,然后按i排序,可以达到预期效果。

如果你想在奇数前加偶数,你可以按i % 2排序。

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

感谢@Stefan的最初想法!