【问题标题】:Ruby custom string sortRuby 自定义字符串排序
【发布时间】:2015-04-22 20:52:10
【问题描述】:

输入字符串:

1654AaBcDddeeFF 

输出字符串:

1456acddeeABDFF

我试过的代码:

test_array = []
'1654AaBcDddeeFF'.each_byte do |char|
  test_array << char
end

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

但我想最后看到大写字符。

【问题讨论】:

  • 所以你必须尽量让你的程序不区分大小写。
  • 你可以重载并编写一些自定义排序。
  • @ChaseGilliam 不是纳粹,但“重载”不是红宝石约定,甚至是不可能的。 Jörg W Mittag 写了一个excellent post 解释这个概念。 Array#sort 还允许您指定任何您想要的自定义排序
  • @engineersmnky 好的,你是对的。但是,您可以 def ... end 是的,Array#sort 是一种更好的方法。

标签: ruby string sorting


【解决方案1】:

这个怎么样?

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

编辑:正如@Cary Swoveland 指出的.chars 只是.each_char.to_a 的快捷方式,因为我们不需要to_a 这里.each_char 是一种更好的使用方法

【讨论】:

  • 这是一个非常狡猾的答案。虽然喜欢这种方法。非常感谢
  • 不错的一个。也许each_char 而不是chars 以避免创建临时数组。
  • 不得不考虑这个问题。非常聪明。
【解决方案2】:

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

str = '1654AaBcDddeeFF'

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

(我只是一个抄写员。)

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

str = '16?54!AaBcDdde,eFF'

你还想将字符“!?,”在开头分组,按照这个顺序,你可以这样写:

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

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

order_hash = Hash[order_array.each_with_index.to_a]

然后:

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

【讨论】:

  • 请注意,这会删除重复的字符。
  • 你可以使用order数组和sort_by { |c| order.index(c) }
  • 看起来不错。但是这里真的发生了排序吗?比如说,当涉及到特殊字符时,它们是根据 ASCII 值排序的吗?对我来说,就符号而言,这看起来只是分组,但不确定,请赐教
  • @Appunu,您必须在 order_array 中包含特殊字符。例如,如果str = 'βΔ3Rαe' 并且我们想修改我的示例以将希腊字母放在末尾(小写然后大写),我们将需要order_array = [*'0'..'9',*'a'..'z',*'A'..'Z',*'α'..'ω',*'Α'..'Ω']str.each_char.sort_by { |c| order_array.index(c) }.join #=&gt; "3eRαβΔ"。另请注意str.each_char.map(&amp;:swapcase).join #=&gt; "βΔ3rαE"
  • 尽管我接受了之前的答案。 @CarySwoveland 提供的这种解决方案是我们需要涉及特殊字符和符号的各种情况下的最佳解决方案。
猜你喜欢
  • 1970-01-01
  • 2019-08-30
  • 1970-01-01
  • 2015-07-25
  • 2021-08-26
  • 2020-05-29
  • 2015-09-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多