I want to specify a custom block method to sort an object array by evaluating two properties. However, after many searches, I didn\'t find to any example without the <=
This will give you ascending order for x
then for y
:
points.sort_by{ |p| [p.x, p.y] }
The best answer is provided by @AJcodez below:
points.sort_by{ |p| [p.x, p.y] }
The "correct" answer I originally provided, while it technically works, is not code I would recommend writing. I recall composing my response to fit the question's use of if
/else
rather than stopping to think or research whether Ruby had a more expressive, succinct way, which, of course, it does.
With a case
statement:
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
With ternary:
ar.sort { |a,b| a.x < b.x ? -1 : (a.x > b.x ? 1 : (a.y <=> b.y)) }
This seems to work:
# 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
There's no need for the spaceship operator ( <=>
) - it seems to be superfluous in Ruby (in terms of syntax efficiency), because Ruby considers 0
to be true, and for this usage specifically (above), you can just put the explicit 0
in the ternary operator.