2

我想对第一个数组进行排序:

 filenames = ["z.pdf", "z.txt", "a.pdf", "z.rf", "a.rf","a.txt", "z.html", "a.html"]

通过以下文件的扩展名数组:

 extensions = ["html", "txt", "pdf", "rf"]

使用sort_by. 但是当我尝试时:

 filenames.sort_by { |x| extensions.index x.split('.')[1] }

我得到:

 ["a.html", "z.html", "z.txt", "a.txt", "a.pdf", "z.pdf", "z.rf", "a.rf"]

扩展名为“txt”和“rf”的文件名没有排序。我试图弄清楚如何sort_by使用元组进行排序,但无法找到sort_by.

如何使用另一个数组对一个数组进行排序sort_by


编辑:

结果应如下所示:

["a.html", "z.html", "a.txt", "z.txt", "a.pdf", "z.pdf", "a.rf", "z.rf"]
4

7 回答 7

3

怎么样:

>> filenames.sort.group_by{ |s| File.extname(s)[1..-1] }.values_at(*extensions).flatten
[
    [0] "a.html",
    [1] "z.html",
    [2] "a.txt",
    [3] "z.txt",
    [4] "a.pdf",
    [5] "z.pdf",
    [6] "a.rf",
    [7] "z.rf"
]

group_by来自 Enumerable,是我们收集工具箱中的一个很好的工具,让我们可以通过“like”属性对事物进行分组。在这种情况下,它对文件扩展名进行分组,使用 检索File.extname,减去其前导 '.'。

了解为什么 File.extname很重要很重要。出于各种原因,一个文件可以有多个由“.”分隔的部分。在这一点上,简单地使用split('.')是灾难的秘诀,因为拆分后的代码将不得不处理两个以上的字符串。其他文件不包含定界“。” 一点也不。File.extname合理地尝试检索在名称中找到的最后一个扩展名,因此它是处理文件名和扩展名的更明智的方式。从文档中:

File.extname("test.rb")         #=> ".rb"
File.extname("a/b/d/test.rb")   #=> ".rb"
File.extname("foo.")            #=> ""
File.extname("test")            #=> ""
File.extname(".profile")        #=> ""
File.extname(".profile.sh")     #=> ".sh"

values_at来自哈希,并按照传入的键/参数的顺序从哈希中提取值。这对于这种情况非常有用,因为我们可以强制值的顺序与键的顺序匹配。当您有一个巨大的散列并想在一个操作中从中挑选某些值时,values_at就是抓取的工具。如果您需要不同的“扩展”顺序,请进行更改extensions,输出将自动反映values_at.

于 2013-05-17T20:08:39.713 回答
3

按扩展数组的索引排序,然后是文件名:

filenames = ["z.pdf", "z.txt", "a.pdf", "z.rf", "a.rf","a.txt", "z.html", "a.html"]
extensions = ["html", "txt", "pdf", "rf"]

p sorted = filenames.sort_by{|fn| [extensions.index(File.extname(fn)[1..-1]), fn]} #[1..-1] chops off the dot
#=> ["a.html", "z.html", "a.txt", "z.txt", "a.pdf", "z.pdf", "a.rf", "z.rf"]
于 2013-05-17T20:09:36.650 回答
3
sorted = filenames.sort_by do |filename|
  extension = File.extname(filename).gsub(/^\./, '')
  [
    extensions.index(extension) || -1,
    filename,
 ]
end
p sorted
# => ["a.html", "z.html", "a.txt", "z.txt", "a.pdf", "z.pdf", "a.rf", "z.rf"]

这使用了这样一个事实,即数组的排序顺序由它们的元素的排序顺序决定,按照它们定义的顺序。这意味着如果sort_by返回一个数组,则数组的第一个元素是主要排序顺序,第二个元素是次要排序顺序,依此类推。我们利用它按扩展名主要,文件名次要排序。

如果扩展不在列表中,此代码将凭借||= -1. 要将未知扩展名放在最后,请替换-1extensions.size.

于 2013-05-17T20:05:48.320 回答
1
filenames.sort_by{|f| f.split(".").map{|base, ext|
  [extensions.index(ext), base]
}}
于 2013-05-17T20:16:54.987 回答
0
extensions = [".html", ".txt", ".pdf", ".rf"]
filenames.sort_by { |file_name_string|
  [ extensions.index( File.extname file_name_string ), file_name_string ]
}
于 2013-05-17T20:16:03.407 回答
0
filenames = ["z.pdf", "z.txt", "a.pdf", "z.rf", "a.rf","a.txt", "z.html", "a.html"]
extensions = ["html", "txt", "pdf", "rf"]
extensions.each_with_object([]){|k,ob| ob << filenames.find_all {|i| File.extname(i)[1..-1] == k }.sort}.flatten
#=> ["a.html", "z.html", "a.txt", "z.txt", "a.pdf", "z.pdf", "a.rf", "z.rf"]
于 2013-05-17T19:49:37.217 回答
-1

无需使用 File 类。只是简单的正则表达式。

filenames.sort_by{|i| i.scan(/\..+$/)[0]}
于 2013-05-17T19:55:22.563 回答