如何在ruby中对文件名进行排序?

luc*_*tis 7 ruby arrays sorting numbers file

是的,它是Ruby 的自然排序方法的副本吗? ,但我认为 dawg 和 Eric 在这里说得更清楚,至少对我来说这些答案更详尽。

我有一个这样的数组:

arr = ["file1.txt", "file11.txt", "file12.txt", "file2.txt", "file3.txt"]
Run Code Online (Sandbox Code Playgroud)

我希望它像这样排序:

arr = ["file1.txt", "file2.txt", "file3.txt", "file11.txt", "file12.txt"]
Run Code Online (Sandbox Code Playgroud)

我怎样才能做到这一点?我试过sort,但对我来说不是很清楚..

我按大小对文件进行排序,如下所示:

files=Dir.entries("./").sort { |f| File.size(f) }.select { |f| File.file?(f) }
Run Code Online (Sandbox Code Playgroud)

daw*_*awg 5

Eric 的答案是仅对文件名中的数字进行自然排序的好方法。如果所有文件名都具有相同的前缀,则有效。

如果您想添加第二个元素(例如,其中没有数字的文件名),您可以使用多元素 sort_by 创建一个列表:

filenames = ["file1.txt", "file11.txt", "file12.txt", "file2.txt", "file3.txt","file.txt", "File.txt"]
filenames.sort_by{ |name| [name[/\d+/].to_i, name] }
=> ["File.txt", "file.txt", "file1.txt", "file2.txt", "file3.txt", "file11.txt", "file12.txt"]
Run Code Online (Sandbox Code Playgroud)

该工具的两个元素sort_by

  1. 如果使用正则表达式找到数字的整数值,name[/\d+/].to_i
  2. 如果没有数字或相同数字,请命名name

更强大的是,您可以按数字拆分整个字符串并将每个字符串转换为 int:

> "abc123def456gh".split(/(\d+)/).map{ |e| Integer(e) rescue e}
=> ["abc", 123, "def", 456, "gh"]
Run Code Online (Sandbox Code Playgroud)

所以你的自然排序变成:

arr.sort_by{ |s| s.split(/(\d+)/).map{ |e| Integer(e) rescue e}}
Run Code Online (Sandbox Code Playgroud)

所以现在名称和数字(甚至是多个名称和数字)被正确处理:

> arr = ["file1.txt", "file11.txt", "file12.txt", "file2.txt", "file3.txt", "gfile10.txt", "gfile1.txt", "gfile.txt", "file.txt", "afile.txt","afile10.txt","afile2.txt" ]
> arr.sort_by{ |s| s.split(/(\d+)/).map{ |e| Integer(e) rescue e}}
=> ["afile2.txt", "afile10.txt", "afile.txt", "file1.txt", "file2.txt", "file3.txt", "file11.txt", "file12.txt", "file.txt", "gfile1.txt", "gfile10.txt", "gfile.txt"]
Run Code Online (Sandbox Code Playgroud)