How can I sort multiple objects by a secondary key when the first one is equal?
In my Book class I have the following method used for sorting
def <=>(other)
printed_on <=> other.printed_on
end
Now I need the books printed the same day (printed_on = other.printed_on) to be sorded by page_number.
Since with sort_by you can pass an array of keys, I have tried
def <=>(other)
[printed_on <=> other.printed_on, page_number <=> other.page_number]
end
but I get
undefined method `>' for [1, 1]:Array
Arrays are compared lexicographically (bold emphasis mine):
Arrays are compared in an “element-wise” manner; the first element of
aryis compared with the first one ofother_aryusing the<=>operator, then each of the second elements, etc… As soon as the result of any such comparison is non zero (i.e. the two corresponding elements are not equal), that result is returned for the whole array comparison.
[This is just a convoluted way of saying "Arrays are compared lexicographically".]
So you could simply use an Array for your comparison:
def <=>(other)
[printed_on, page_number] <=> [other.printed_on, other.page_number]
end
Your method violates the contract of <=> (bold emphasis mine):
Your implementation of
#<=>should return one of the following values:-1,0,1ornil.
There are only four allowed return values for a conforming implementation of <=>:
-1: less-than0: equal+1: greater-thannil: uncomparable (partially ordered)You are returning neither of those four, you are returning an Array. As always, if you break the contract, strange things can happen.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With