2010-10-09 73 views
5

我不得不下面的代码在红宝石:在Ruby中,如何在目录列表中的文件夹之前列出/排序文件?

<% 
    files = Dir.glob('/**/*') 
    files.each do |file| 
    puts file 
    end 
%> 

它输出(举例来说):

/dirA/file1.txt 
/dirA/file2.txt 
/dirB/file1.txt 
/file1.txt 
/file2.txt 
/subdirA/file1.txt 

我希望它输出这样的:

/file1.txt 
/file2.txt 
/dirA/file1.txt 
/dirA/file2.txt 
/dirB/file1.txt 
/subdirA/file1.txt 

基本上,我想要在目录之前显示文件。有我可以使用的排序命令吗?

回答

6

我相信这应该为你工作:

files = Dir.glob('**/*') 
files = files.map { |file| [file.count("/"), file] } 
files = files.sort.map { |file| file[1] } 
files.each do |file| 
    puts file 
end 

变化"/"?/如果你在Ruby 1.8中。

或者,作为一个班轮::)

Dir.glob('**/*').map { |file| [file.count("/"), file] }.sort.map { |file| file[1] }.each { |file| puts file } 
+0

的作品!谢谢! – 2010-10-09 01:28:17

+2

'Enumerable#sort_by'使Schwartzian变换更容易遵循,而'String#count'对1.8和1.9:'files = Dir.glob('**/*')都有效。sort_by {| file | [file.count(“/”),file]}'。 (数组仍然需要用相同的斜杠数来打破文件名之间的关系。) – bk1e 2010-10-09 06:53:22

+0

我不明白为什么会需要'sort_by';数组排序标准应该没问题,不是吗? (比较第一个元素,如果相同,则转到下一个元素。)我不想在比较块中进行计数,因为这样做效率不高(我不认为Ruby本身足够聪明以便自行记忆)。我不知道'String#count';感谢那。使用它肯定会更优雅。我会编辑它。 – Amadan 2010-10-09 17:55:36

1
d,f = Dir.glob('*').partition{|d|test(?d,d)} 
d.sort.each{|x|puts x} 
f.sort.each{|y|puts y}