如何在ruby中对包含数字和字母的字符串数组进行排序

如何在ruby中对包含数字和字母的字符串数组进行排序,ruby,Ruby,我有一个字符串数组,每个元素包含两个或三个数字、一个空格和一个字母 array = [ "293 C", "401 B","421 B","428 B","439 B","315 C","529 B","560 B","566 B", "567 B","616 B","39 C","28 C","30 C","698 B","719 B","722 B", "640 B","786 B","645 B","236 B","255 B","442 C","446 C","477 C", "

我有一个字符串数组,每个元素包含两个或三个数字、一个空格和一个字母

array = [ "293 C",
 "401 B","421 B","428 B","439 B","315 C","529 B","560 B","566 B",
 "567 B","616 B","39 C","28 C","30 C","698 B","719 B","722 B",
 "640 B","786 B","645 B","236 B","255 B","442 C","446 C","477 C",
 "368 C","381 C","399 C","406 C","504 C","505 C","515 C","116 C",
 "138 C","147 C","174 C"]
因此,我需要的是这样的东西

["236 B","255 B","401 B","421 B","428 B","439 B","529 B","560 B",
"566 B","567 B","616 B","640 B","645 B","698 B","719 B","722 B",
"786 B","28 C","30 C", "39 C","116 C","138 C","147 C","174 C", "293 C",
"315 C", "368 C", "381 C","399 C","406 C","442 C","446 C",
"477 C","504 C","505 C","515 C"]
换句话说,我需要使用字母后缀作为主要排序键,数字前缀的整数值作为次要排序键对字符串列表进行排序

我尝试了sort_by方法,但它只允许我按字母对数组排序(如果我先拆分每个元素)


数组作为第一个元素进行比较;如果一个元素相等,则比较下一个元素。

这里有一种方法:

array.sort_by { |e| [e[-1], e.to_i] }
另一种选择:

array.sort_by {|s| [s[/[a-zA-Z]+/], s.to_i]}

                        ^                      grab the letter or letters and the end
                                      ^        convert the digits at the front
或者,正如评论中指出的,最好不要使用基于拉丁语的字符类

你可以做:

array.sort_by { |s| [s[s.index(/[\t ]\S/)+1..-1], s.to_i] }

                                 ^       tab, space followed by not a space
或者

或者

array.sort_按{s|s[-1][“236 B”,“255 B”,“401 B”,“…,“722 B”,“786 B”,
#“28摄氏度”、“30摄氏度”、“39摄氏度”、“50摄氏度”、“515摄氏度”]
注:

array.map{| s | s[-1][“B236”、“B255”、“B401”、“B722”、“B786”,
#“C028”、“C030”、“C039”、…、“C505”、“C515”]

这个答案与@Amadan的答案有什么不同?@mudasobwa没有太大区别,只是数组的形成方式不同;而且它可以在一行中使用,而无需
(顺便说一句,我在发布时没有注意到Amadan的答案).splat是多余的。@mudasobwa:是的。我在应用它时不一致。但AutoPlats数组在多个赋值中的规则可能是我真正不喜欢的Ruby的一个部分……或者
{s|[s[/\D+/],s.to_I]}
s[/\D+/]
拾取字母前的前导空格。如果输入数据中存在“噪音”,例如两列之间的空格数不一致,则会更改排序。
s[s.index(/\s\s/)+1..-1]
可能更好。@dawg,认为字母是拉丁语的意思是一种简单的方法。如果我们是tête-tête,êêиêêêêиêêêêê-tête,êêêêêêêêêêê23应该这样做。谷歌翻译说Сзззззззззззззза1072
array.sort_by {|s| [s[/[a-zA-Z]+/], s.to_i]}

                        ^                      grab the letter or letters and the end
                                      ^        convert the digits at the front
array.sort_by { |s| [s[s.index(/[\t ]\S/)+1..-1], s.to_i] }

                                 ^       tab, space followed by not a space
array.sort_by { |s| [s[/[^\d\t ]+/], s.to_i] }

                            ^             skip digits and spaces -- the rest
array.sort_by { |s| [s[/\p{L}+/], s.to_i] }

                           ^ code point in the category "letter".
array.sort_by { |s| s[-1] << s[/\d+/].rjust(3, '0') }
  #=> ["236 B", "255 B", "401 B",..., "722 B", "786 B",
  #     "28 C",  "30 C",  "39 C",..., "505 C", "515 C"]
array.map { |s| s[-1] << s[/\d+/].rjust(3, '0') }.sort
  #=> ["B236", "B255", "B401",..., "B722", "B786",
  #    "C028", "C030", "C039",..., "C505", "C515"]