2010-05-28 11 views
13

Estoy usando RecursiveDirectoryIterator y RecursiveIteratorIterator para compilar un árbol de lista de archivos usando el código siguiente. Necesito que la lista sea ordenada, ya sean directorios, luego archivos alfabéticamente o simplemente alfabéticamente.Ordenar la lista de directorios utilizando RecursiveDirectoryIterator

¿Alguien me puede decir cómo ordenar la lista de archivos?

$dir_iterator = new RecursiveDirectoryIterator($groupDirectory); 
$iterator = new RecursiveIteratorIterator($dir_iterator, RecursiveIteratorIterator::SELF_FIRST); 
foreach ($iterator as $file) { 
    // do stuff with $file 
} 
+0

posible duplicado de [después de usar $ files = new DirectoryIterator() en PHP, ¿cómo se ordenan los elementos?] (Http://stackoverflow.com/questions/1076881/after-using-files-new-directoryiterator-in- php-how-do-you-sort-the-items) –

+0

[salathe/spl-examples - Clasificación de Iteradores] (https://github.com/salathe/spl-examples/wiki/Sorting-Iterators) – hakre

Respuesta

1

Esto no es posible utilizando el propio iterador. He visto una extensión de la clase Iterator en alguna parte de SO que clasificaba pero recuerdo haber tenido problemas con ella.

¿Quizás las respuestas a this question ayudan, a pesar de que apuntan lejos del iterador?

Actualización: Here es una tontería para su pregunta con algunas respuestas, aunque no muchas.

+0

Dang. Pensé que estos iteradores realmente me ayudarían. Gracias Pekka. –

23

Hay varias opciones disponibles, que puede usar para ordenar un iterador de una forma u otra. La mejor opción dependerá en gran medida de cómo quiera manipular el contenido del iterador, qué quiere obtener del iterador y, de hecho, qué tanto o tan poco del iterador realmente desea/necesita.

Los enfoques pueden variar; haciendo uso de clases como SplHeap (o Min, Max variedades), SplPriorityQueue (tal vez para cosas como el tamaño de archivo) o simplemente envolviendo su iterador en algo como ArrayObject que puede ordenar sus propios contenidos.

Usaré un SplHeap como ejemplo. Desde desea organizar todo el contenido de la RecursiveDirectoryIterator alfabéticamente entonces algo parecido a lo siguiente podría ser utilizado:

class ExampleSortedIterator extends SplHeap 
{ 
    public function __construct(Iterator $iterator) 
    { 
     foreach ($iterator as $item) { 
      $this->insert($item); 
     } 
    } 
    public function compare($b,$a) 
    { 
     return strcmp($a->getRealpath(), $b->getRealpath()); 
    } 
} 

$dit = new RecursiveDirectoryIterator("./path/to/files"); 
$rit = new RecursiveIteratorIterator($dit); 
$sit = new ExampleSortedIterator($rit); 
foreach ($sit as $file) { 
    echo $file->getPathname() . PHP_EOL; 
} 

El criterio de ordenación es alfabética, archivos y carpetas de mezcla:

./apple 
./apple/alpha.txt 
./apple/bravo.txt 
./apple/charlie.txt 
./artichoke.txt 
./banana 
./banana/aardvark.txt 
./banana/bat.txt 
./banana/cat.txt 
./beans.txt 
./carrot.txt 
./cherry 
./cherry/amy.txt 
./cherry/brian.txt 
./cherry/charlie.txt 
./damson 
./damson/xray.txt 
./damson/yacht.txt 
./damson/zebra.txt 
./duck.txt 
+0

¡Muchas gracias! – eisberg

0

Sönke Ruempler tiene una gran solución:

class SortingIterator implements IteratorAggregate 
{ 

     private $iterator = null; 

     public function __construct(Traversable $iterator, $callback) 
     { 
       if (!is_callable($callback)) { 
         throw new InvalidArgumentException('Given callback is not callable!'); 
       } 

       $array = iterator_to_array($iterator); 
       usort($array, $callback); 
       $this->iterator = new ArrayIterator($array); 
     } 


     public function getIterator() 
     { 
       return $this->iterator; 
     } 
} 

Fuente: http://www.ruempler.eu/2008/08/09/php-sortingiterator

+2

Al publicar un enlace como respuesta, incluya suficiente contenido que la respuesta sea útil por sí solo, en caso de que el enlace se rompa más tarde. –

Cuestiones relacionadas