I want to sort an array by strings first and then numbers. How do I do this?
Normally, alphabetization is done with numbers first. If you want to alphabetize something where letters are alphabetized before numbers, you will need to alter the compare function used.
# I realize this function could be done with less if-then-else logic,
# but I thought this would be clearer for teaching purposes.
def String.mysort(other)
length = (self.length < other.length) ? self.length : other.length
0.upto(length-1) do |i|
# normally we would just return the result of self[i] <=> other[i]. But
# you need a custom sorting function.
if self[i] == other[i]
continue # characters the same, skip to next character.
else
if self[i] ~= /[0-9]/
if other[i] ~= /[0-9]/
return self[i] <=> other[i] # both numeric, sort normally.
else
return 1 # self is numeric, other is not, so self is sorted after.
end
elsif other[i] ~= /[0-9]/
return -1 # self is not numeric, other is, so self is sorted before.
else
return self[i] <=> other[i] # both non-numeric, sort normally.
end
end
end
# if we got this far, the segments were identical. However, they may
# not be the same length. Short sorted before long.
return self.length <=> other.length
end
['0','b','1','a'].sort{|x,y| x.mysort(y) } # => ['a', 'b', '0', '1']