Ruby 按字符和数字对数组排序

Ruby 按字符和数字对数组排序,ruby,algorithm,sorting,numbers,character,Ruby,Algorithm,Sorting,Numbers,Character,我尝试对字符串数组进行如下排序: ['A1', 'A5', 'A13', 'B2', 'B5', 'B13'] ['A1', 'A13', 'A5', 'B13', 'B2', 'B5'] 当然,标准算法是这样分类的: ['A1', 'A5', 'A13', 'B2', 'B5', 'B13'] ['A1', 'A13', 'A5', 'B13', 'B2', 'B5'] 问题是,也可能存在如下字符串:'B2K'或'B21A' 我如何让Ruby像第一个一样,以人类逻辑的方式对这些字符串进

我尝试对字符串数组进行如下排序:

['A1', 'A5', 'A13', 'B2', 'B5', 'B13']
['A1', 'A13', 'A5', 'B13', 'B2', 'B5']
当然,标准算法是这样分类的:

['A1', 'A5', 'A13', 'B2', 'B5', 'B13']
['A1', 'A13', 'A5', 'B13', 'B2', 'B5']
问题是,也可能存在如下字符串:
'B2K'
'B21A'

我如何让Ruby像第一个一样,以人类逻辑的方式对这些字符串进行排序。我想在不向字符串添加尾随零的情况下实现这一点,这是一个显而易见的解决方案


我想知道这是怎么回事

本质上,您希望对字符串
“A13”
进行排序,就好像它是元组
[“A”,13]
。很容易将
“A13”
转换为
[“A”,13]

str = "A13"
p [ str[0], str[1..-1].to_i ]
# => ["A", 13]
幸运的是,Ruby已经知道如何像这里生成的那样对数组进行排序,所以您需要做的就是告诉它从每个字符串创建这样一个数组,并在排序比较中使用它。为此,Ruby有:

此代码假定每个字符串都有一个字母后跟一个或多个数字。对于更复杂的字符串,如
“B21A”
,您可能需要使用正则表达式来提取每个部分,例如:

MATCH_PARTS_EXPR = /^([A-Z]+)(\d+)(.+)?/
此正则表达式假定每个字符串都有一个或多个大写字母,后跟一个或多个数字,还可以选择后跟其他字符。我们可以这样使用它,例如将
“B21A”
转换为
[“B”,21,“A”]

我们可以像以前一样将其与
sort\u by
一起使用:

arr = ["B2", "B21A", "A1", "A5", "B13", "A13", "B5"]

arr.sort_by do |str|
  letters, numbers, rest = str.match(MATCH_PARTS_EXPR).captures
  [ letters, numbers.to_i, *rest ]
end
# => ["A1", "A5", "A13", "B2", "B5", "B13", "B21A"]

本质上,您希望对字符串
“A13”
进行排序,就好像它是元组
[“A”,13]
。很容易将
“A13”
转换为
[“A”,13]

str = "A13"
p [ str[0], str[1..-1].to_i ]
# => ["A", 13]
幸运的是,Ruby已经知道如何像这里生成的那样对数组进行排序,所以您需要做的就是告诉它从每个字符串创建这样一个数组,并在排序比较中使用它。为此,Ruby有:

此代码假定每个字符串都有一个字母后跟一个或多个数字。对于更复杂的字符串,如
“B21A”
,您可能需要使用正则表达式来提取每个部分,例如:

MATCH_PARTS_EXPR = /^([A-Z]+)(\d+)(.+)?/
此正则表达式假定每个字符串都有一个或多个大写字母,后跟一个或多个数字,还可以选择后跟其他字符。我们可以这样使用它,例如将
“B21A”
转换为
[“B”,21,“A”]

我们可以像以前一样将其与
sort\u by
一起使用:

arr = ["B2", "B21A", "A1", "A5", "B13", "A13", "B5"]

arr.sort_by do |str|
  letters, numbers, rest = str.match(MATCH_PARTS_EXPR).captures
  [ letters, numbers.to_i, *rest ]
end
# => ["A1", "A5", "A13", "B2", "B5", "B13", "B21A"]

@rcheetah我认为David Koelle的aphanum算法将是一个很好的起点,它的工作原理以及ruby实现也有很好的描述。它本质上是为您正在排序的每个项目创建字符和数字的“块”,然后进行比较。如果它们是字符串,请这样写。目前,它们是常量。欢迎使用堆栈溢出。读作“及”。你试图用什么方法来解决这个问题?我们是来帮助你的,但我们希望你能向我们展示你的努力。也是一本很好的读物。@rcheetah我认为David Koelle的aphanum算法将是一个很好的起点。它的工作原理以及ruby实现也有很好的描述。它本质上是为您正在排序的每个项目创建字符和数字的“块”,然后进行比较。如果它们是字符串,请这样写。目前,它们是常量。欢迎使用堆栈溢出。读作“及”。你试图用什么方法来解决这个问题?我们是来帮助你的,但我们希望你能向我们展示你的努力。这也是一本很好的读物。也许可以坚持下去也在那里?当然,如果你想就地排序,请使用
排序依据
。亲爱的投反对票者:请花点时间留下评论,解释投反对票的原因。如果没有我的答案,我会很感激有机会改进它。有时人们会投反对票,因为他们有一整袋的选票,并试图通过把它们撒在周围来证明自己很酷。好的答案总能赢得选票;尽你所能回答。嗯。。。您没有真正解释为什么使用
sort\u by
vs.
sort
<代码>排序将为每次比较计算排序标准,当我们不对基本对象进行排序时,这是非常昂贵的
sort_by
执行一个“”来维护中间计算值,避免每次重新计算。看,可能会发出砰的一声
也在那里?当然,如果你想就地排序,请使用
排序依据
。亲爱的投反对票者:请花点时间留下评论,解释投反对票的原因。如果没有我的答案,我会很感激有机会改进它。有时人们会投反对票,因为他们有一整袋的选票,并试图通过把它们撒在周围来证明自己很酷。好的答案总能赢得选票;尽你所能回答。嗯。。。您没有真正解释为什么使用
sort\u by
vs.
sort
<代码>排序
将为每次比较计算排序标准,当我们不对基本对象进行排序时,这是非常昂贵的
sort_by
执行一个“”来维护中间计算值,避免每次重新计算。看见