Reputation: 83
Input string:
1654AaBcDddeeFF
Output string:
1456acddeeABDFF
Code I tried:
test_array = []
'1654AaBcDddeeFF'.each_byte do |char|
test_array << char
end
test_array.sort.pack('C*')
# => 1456ABDFFacddee
But I would like to see the upper case characters at last.
Upvotes: 5
Views: 1032
Reputation: 110685
Since @hirolau's already taken swapcase
, I offered an alternative (even though I prefer his answer). Alas, @Stefan identified a flaw, but suggested a nice fix:
str = '1654AaBcDddeeFF'
order_array = [*'0'..'9',*'a'..'z',*'A'..'Z']
str.each_char.sort_by { |c| order_array.index(c) }.join
#=> "1456acdeABDF"
(I am a mere scribe.)
One advantage of this approach is that you could use it for other orderings. For example, if:
str = '16?54!AaBcDdde,eFF'
and you also wanted to group the characters `'!?,' at the beginning, in that order, you could write:
order_array = [*'!?,'.chars,*'0'..'9',*'a'..'z',*'A'..'Z']
str.each_char.sort_by { |c| order_array.index(c) }.join
#=> "!?,1456acdeABDF"
We can make this a bit more efficient by converting order_array
to a hash. For the last example:
order_hash = Hash[order_array.each_with_index.to_a]
then:
str.each_char.sort_by { |c| order_hash[c] }.join
# => "!?,1456acddeeABDFF"
Upvotes: 5
Reputation: 13901
What about this?
p '1654AaBcDddeeFF'.each_char.sort_by(&:swapcase).join #=> "1456acddeeABDFF"
Edit: As @Cary Swoveland pointed out .chars
is just a shortcut for .each_char.to_a
and since we do not need to to_a
here .each_char
is a better method to use
Upvotes: 13