如何使用 sort_by 按字母顺序排序,然后按数字排序,然后按特殊字符排序

use*_*916 4 ruby ruby-on-rails

我有一个数组:

\n
arr = ["Bar", "abc", "foo", "1", "20\xe2\x80\x9d, "10", "_def"]\n
Run Code Online (Sandbox Code Playgroud)\n

我需要首先按不区分大小写的字母顺序进行排序,然后按数字顺序排序,然后是特殊字符。

\n

我正在尝试使用sort_by

\n
irb(main):071:0> arr.sort_by {|s| [s[/[0-9a-z]+/], s.to_i]}\n=> ["1", "10", "20", "abc", "Bar", "_def", "foo"]\n
Run Code Online (Sandbox Code Playgroud)\n

输出必须是:

\n
arr = ["abc", "Bar", "foo", "1", \xe2\x80\x9c10\xe2\x80\x9d, \xe2\x80\x9c20", "_def"]\n
Run Code Online (Sandbox Code Playgroud)\n

Ste*_*fan 5

来自文档

\n
\n

数组以 \xe2\x80\x9celement-wise\xe2\x80\x9d 方式进行比较;使用运算符将​​ 的第一个元素ary与第一个元素进行比较,然后将第二个元素中的每个元素进行比较,依此类推\xe2\x80\xa6other_ary<=>

\n
\n

您可以通过创建排序组来利用此行为:

\n
arr = ["Bar", "abc", "foo", "1", "20", "10", "_def"]\n\narr.sort_by do |s|\n  case s\n  when /^[a-z]/i\n    [1, s.downcase]\n  when /^\\d/\n    [2, s.to_i]\n  else\n    [3, s]\n  end\nend\n#=> ["abc", "Bar", "foo", "1", "10", "20", "_def"]\n
Run Code Online (Sandbox Code Playgroud)\n

第一个元素 ( 1, 2, 3) 定义组的位置:字母字符串位于第一个位置,数字字符串位于第二个位置,其余位于第三个位置。在每个组中,元素按第二个元素排序:包含字母的字符串按其小写值排序,数字字符串按其整数值排序,其余的则按其自身排序。

\n