2010-10-09 14 views
5

tengo que siguiente código en Ruby:En Ruby, ¿cómo enumera/ordena los archivos antes que las carpetas en una lista de directorios?

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

Se da salida (por ejemplo):

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

quiero que la salida de esta manera:

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

Básicamente, Me gustaría tener los archivos mostrados antes de los directorios. ¿Hay algún comando de clasificación que pueda usar?

Respuesta

6

creo que esto debería funcionar para usted:

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

Cambio "/" a ?/ si estás en Rubí 1.8.

O, como una sola línea: :)

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

que funciona !! ¡GRACIAS! –

+2

'Enumerable # sort_by' hace que la transformación de Schwartz sea más fácil de seguir, y' String # count' funciona tanto en 1.8 como en 1.9: 'files = Dir.glob ('**/*'). Sort_by {| file | [file.count ("/"), file]} '. (La matriz sigue siendo necesaria para romper las relaciones entre nombres de archivos con el mismo recuento de barras). – bk1e

+0

No entiendo por qué 'sort_by' sería necesario; el criterio de clasificación de matriz debería estar bien, ¿no? (compare los primeros elementos, si es el mismo, pase al siguiente). No quiero contar dentro del bloque de comparación ya que sería ineficiente (no creo que Ruby sea lo suficientemente inteligente como para memorizar por sí mismo). No sabía sobre 'String # count'; gracias por eso. Usar eso definitivamente sería más elegante. Lo editaré en. – Amadan

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