Ruby custom string sort
输入字符串:
输出字符串:
号
我尝试的代码:
1 2 3 4 5 6 7
| test_array = []
'1654AaBcDddeeFF'.each_byte do |char|
test_array << char
end
test_array.sort.pack('C*')
# => 1456ABDFFacddee |
但我最后还是想看看大写字母。
- 所以你必须让你的程序不区分大小写。
- 您可以重载<=>并编写一些自定义排序。
- @Chasegilliam不是纳粹,但"过载"不是Ruby惯例,甚至不可能。J&246;RG W Mittag写了一篇很好的文章来解释这个概念。另外,Array#sort允许您指定任何需要的自定义排序。
- @工程师们,好的,你是对的。但是,您可以定义<=>…是的,数组排序是一种更好的方法。
- 提醒我stackoverflow.com/q/28413845/477037
这个怎么样?
1
| p '1654AaBcDddeeFF'.each_char.sort_by(&:swapcase).join #=>"1456acddeeABDFF" |
编辑:正如@cary swoveland指出的,.chars只是.each_char.to_a的一个捷径,因为我们不需要to_a这里.each_char是一个更好的使用方法。
- 这是一个非常狡猾的答案。不过,喜欢这种方法。谢谢
- 不错。可能是each_char而不是chars,以避免创建临时数组。
- 不能打败这个!
- 想了一会儿这个。非常聪明。
由于@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" |
。
- 请注意,这将删除重复的字符。
- 您可以使用order数组和sort_by { |c| order.index(c) }数组。
- 看起来不错。但是实际的排序是在这里进行的吗?比如说,当涉及到特殊字符时,它们是基于ASCII值排序的吗?在我看来,符号只是一个分组,但我不确定,请启发我。
- @appunu,您必须在order_数组中包含特殊字符。例如,如果str = 'βΔ3Rαe'和我们想修改我的示例,将希腊字母放在末尾(小写然后大写),我们需要order_array = [*'0'..'9',*'a'..'z',*'A'..'Z',*'α'..'ω',*'Α'..'Ω']和str.each_char.sort_by { |c| order_array.index(c) }.join #=>"3eRαβΔ"。另请注意str.each_char.map(&:swapcase).join #=>"βΔ3rαE"。
- @caryswoveland good point,swapcase只适用于a-z
- 尽管我接受了先前的回答。@caryswoveland提供的这个解决方案是我们需要涉及特殊字符和符号的各种情况下的最佳解决方案。