I am trying to sort an array of words in Ruby 1.8.7 by an insane set of rules. This can be simplified to wanting to sort case-insensitive .sort_by{|a| a.downcase} then re-sort case-sensitive but only if the 2 strings are the same.
I would think you could just .downcase compare only the strings that are equal and then sort just those, sending 0 for the rest. But no, that isn't working for me.
Here's what I have:
["A", "a", "a.", "A.", "Ba", "ba"].sort_by{|a| a.downcase}.sort{|a,b| a.downcase==b.downcase ? a<=>b : 0 }
Desired output:
["A", "a", "A.", "a.", "Ba", "ba"]
Thanks for your help.
If a.downcase == b.downcase then you want to sort using a case-sensitive comparison, right? That really means that you want to sort by the pair [a.downcase, a] and arrays in Ruby compare element by element so you just want:
array.sort_by { |s| [ s.downcase, s ] }
Suppose sort_by is comparing two arrays a1 and a2 to see which one goes first. That's just an a1 <=> a2 call. If a1[0] != a2[0] then the spaceship operator won't have to look at the second elements of the arrays to break a tie because there is no tie and <=> can return +1 or -1 right away. If a1[0] == a2[0] then a1[0] <=> a2[0] is 0 and the spaceship has to look at the second elements to see how to break the tie (or leave the tie as-is if a1 == a2). That sounds like the comparison logic you're after.
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