To guarantee ascending order in both columns we can compare by column when there is no nil
and by max value when there is:
.sort { |(a0, a1), (b0, b1)|
if [a0, b0].none?(&:nil?)
a0 <=> b0
elsif [a1, b1].none?(&:nil?)
a1 <=> b1
else
a0, a1, b0, b1 = [a0, a1, b0, b1].map(&:to_i)
[[a0, a1].max, a0, a1] <=> [[b0, b1].max, b0, b1]
end
}
- Compare two items at a time
- If the left columns are both positive integers then use that to sort.
- this works because if they both have numbers then the right number is always correct relative to the left, so sorting on the left gets you the right result.
- If the right columns are both positive integers then use that to sort.
- we know it's not a matched pair and both left numbers are nil and both rights are comparable so...
- Convert all the nils to something we can work with (
.to_i
makes them zero). - Otherwise, create arrays to sort, with the 1st element of each array being the non-null (non-zero at this point) number.
.max
is just an easy way of getting the non-zero one.