paulguy
paulguy

Reputation: 1115

Ruby sorting based on an if statement

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

Answers (1)

mu is too short
mu is too short

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

Related Questions