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

时间:2017-07-21 16:55:34

标签: 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",
 "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方法,但它只允许我按字母对数组进行排序(如果我先拆分每个元素)

5 个答案:

答案 0 :(得分:5)

watch_indexes

阵列比较作为他们的第一个元素;如果元素相等,则比较下一个元素。

答案 1 :(得分:2)

另一种选择:

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".

答案 2 :(得分:1)

这是一种方法:

array.sort_by { |e| [e[-1], e.to_i] }

答案 3 :(得分:1)

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"]

答案 4 :(得分:0)

arr.sort_by { |e| e.split.reverse.map { |s| s.to_i(36) } }