15

我想指定一个自定义块方法,通过评估两个属性来对对象数组进行排序。但是,经过多次搜索,我没有找到任何没有<=>运算符的示例。

我想a比较b

if a.x less than b.x return -1
if a.x greater than b.x return 1
if a.x equals b.x, then compare by another property , like a.y vs b.y

这是我的代码,它不起作用:

ar.sort! do |a,b|
   if a.x < b.y return -1
   elseif a.x > b.x return 1
   else return a.y <=> b.y
end

此块在函数内,return正在退出函数并返回-1

4

3 回答 3

33

x这将为您提供then for 的升序y

points.sort_by{ |p| [p.x, p.y] }
于 2013-03-14T05:28:18.553 回答
22

最佳答案由以下@AJcodez 提供:

points.sort_by{ |p| [p.x, p.y] }

我最初提供的“正确”答案虽然在技术上有效,但不是我建议编写的代码。我记得我的回答是为了适应问题对if/的使用,else而不是停下来思考或研究 Ruby 是否有一种更具表现力、更简洁的方式,当然,它确实如此。


声明case

ar.sort do |a, b|
  case
  when a.x < b.x
    -1
  when a.x > b.x
    1
  else
    a.y <=> b.y
  end
end 

使用三元:

ar.sort { |a,b| a.x < b.x ? -1 : (a.x > b.x ? 1 : (a.y <=> b.y)) }
于 2013-03-14T04:23:10.200 回答
0

这似乎有效:

# Ascending
ar.sort! do |a,b|
  (a-b).abs() > 0 ? a-b : 0
end

# Descending
ar.sort! do |a,b|
  (a-b).abs() > 0 ? b-a : 0
end

不需要 spaceship 运算符 ( <=>) - 它在 Ruby 中似乎是多余的(就语法效率而言),因为 Ruby 认为0是正确的,并且对于这种用法特别是(上面),您可以将显式0放在三元中操作员。

于 2017-06-12T17:45:00.460 回答