Ruby自定义字符串排序

Ruby custom string sort

输入字符串:

1
1654AaBcDddeeFF

输出字符串:

1
1456acddeeABDFF

我尝试的代码:

1
2
3
4
5
6
7
test_array = []
'1654AaBcDddeeFF'.each_byte do |char|
  test_array << char
end

test_array.sort.pack('C*')
# => 1456ABDFFacddee

但我最后还是想看看大写字母。


这个怎么样?

1
p '1654AaBcDddeeFF'.each_char.sort_by(&:swapcase).join #=>"1456acddeeABDFF"

编辑:正如@cary swoveland指出的,.chars只是.each_char.to_a的一个捷径,因为我们不需要to_a这里.each_char是一个更好的使用方法。


由于@hirolau已经接手了swapcase,我提出了一个替代方案(尽管我更喜欢他的答案)。唉,@stefan发现了一个缺陷,但提出了一个很好的解决方法:

1
2
3
4
5
str = '1654AaBcDddeeFF'

order_array = [*'0'..'9',*'a'..'z',*'A'..'Z']
str.each_char.sort_by { |c| order_array.index(c) }.join
  #=>"1456acdeABDF"

(我只是个抄写员。)

这种方法的一个优点是,您可以将它用于其他订单。例如,如果:

1
str = '16?54!AaBcDdde,eFF'

你还想把角色分组"'!?,'开始时,按这个顺序,你可以写:

1
2
3
order_array = [*'!?,'.chars,*'0'..'9',*'a'..'z',*'A'..'Z']
str.each_char.sort_by { |c| order_array.index(c) }.join
  #=>"!?,1456acdeABDF"

我们可以通过将order_array转换为哈希来提高效率。对于最后一个示例:

1
order_hash = Hash[order_array.each_with_index.to_a]

然后:

1
2
str.each_char.sort_by { |c| order_hash[c] }.join
  # =>"!?,1456acddeeABDFF"