Reputation: 1115
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.
Upvotes: 3
Views: 253
Reputation: 434675
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.
Upvotes: 4