Ruby on rails 如何在Ruby中创建自定义排序方法

Ruby on rails 如何在Ruby中创建自定义排序方法,ruby-on-rails,ruby,Ruby On Rails,Ruby,我想指定一个自定义块方法,通过计算两个属性对对象数组进行排序。然而,经过多次搜索,我没有找到任何没有操作符的示例 我想比较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.

我想指定一个自定义块方法,通过计算两个属性对对象数组进行排序。然而,经过多次搜索,我没有找到任何没有
操作符的示例

我想比较
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
ar.sort!做| a,b|
如果a.xb.x返回1
否则返回a.y b.y
结束
此块位于函数
return
中,退出函数并返回
-1
由@AJcodez提供如下信息:

points.sort_by{ |p| [p.x, p.y] }
我最初提供的“正确”答案虽然在技术上可行,但并不是我建议编写的代码。我记得我的回答是为了适应问题中使用的
if
/
else
,而不是停下来思考或研究Ruby是否有一种更具表达力、更简洁的方式,当然,它确实如此


使用
案例
语句:

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 do | a,b|
案例
当a.xb.x时
1.
其他的
a、 y b.y
结束
结束
对于三元:

ar.sort { |a,b| a.x < b.x ? -1 : (a.x > b.x ? 1 : (a.y <=> b.y)) }
ar.sort{a,b | a.xb.x?1:(a.y b.y))}

这将为
x
提供升序,然后为
y
提供升序:

points.sort_by{ |p| [p.x, p.y] }
这似乎有效:

# 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
放在三元操作符中。

为什么不使用排序方法呢?@Gashner我正在使用它,但是我打算自定义评估。为什么排除了
?因为你想用很难的方法来解决这个问题?这个问题已经回答了,但是我想指出,你的代码的问题是由于错误的if语法造成的。您只需将其更改为“if a.xb.x return 1 else return a.x b.x end”``确保
end
if块。此外,您有时使用
b.y
而不是
b.x
+1进行
sort\u by
Array#
的排序,这正是OP所希望的语义。这非常优雅!做得好-应该是可以接受的答案,对于小型阵列,IMHO
排序依据将较慢。抛出一个大数组或更复杂的访问作为排序键的值的方法,它可以很快超过常规的
排序
例程。出于可读性/维护原因,不建议使用ruby中的多级三元语句。AJcodez下面的答案比我这里的答案要好;用它来代替。不是并且将修改接收器(
ar
)。而
排序
速度更快,这种行为需要注意。