2010-10-09 26 views
5

tôi phải đoạn mã sau trong ruby:Trong Ruby, làm thế nào để bạn liệt kê/sắp xếp các tập tin trước các thư mục trong danh sách thư mục?

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

Nó ra (ví dụ):

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

Tôi muốn nó ra nó như thế này:

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

Về cơ bản, tôi muốn hiển thị các tệp trước các thư mục. Có một lệnh sắp xếp tôi có thể sử dụng?

Trả lời

6

Tôi tin rằng điều này sẽ làm việc cho bạn:

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

Thay đổi "/" để ?/ nếu bạn đang ở trên Ruby 1,8.

Hoặc, như một lớp lót: :)

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

mà làm việc !! CẢM ƠN! –

+2

'Enumerable # sort_by' làm cho phép biến đổi Schwartz trở nên dễ dàng hơn, và' String # count' hoạt động trên cả 1.8 và 1.9: 'files = Dir.glob ('**/*'). Sort_by {| file | [file.count ("/"), tệp]} '. (Mảng vẫn còn cần thiết để phá vỡ các mối quan hệ giữa các tên tập tin với cùng một dấu gạch chéo.) – bk1e

+0

Tôi không hiểu tại sao 'sort_by' là cần thiết; tiêu chí phân loại mảng sẽ không sao, phải không? (so sánh các phần tử đầu tiên, nếu tương tự, chuyển sang phần tiếp theo.) Tôi không muốn đặt đếm bên trong khối so sánh vì nó sẽ không hiệu quả (tôi không nghĩ Ruby đủ thông minh để tự ghi nhớ). Tôi không biết về 'String # count'; cảm ơn vì điều đó. Sử dụng điều đó chắc chắn sẽ thanh lịch hơn. Tôi sẽ chỉnh sửa nó. – Amadan

1
d,f = Dir.glob('*').partition{|d|test(?d,d)} 
d.sort.each{|x|puts x} 
f.sort.each{|y|puts y} 
Các vấn đề liên quan