Сортировка списка каталогов с помощью RecursiveDirectoryIterator

Я использую RecursiveDirectoryIterator и RecursiveIteratorIterator чтобы построить дерево списка файлов, используя код, как показано ниже. Мне нужно, чтобы список был отсортирован - либо каталоги, либо файлы в алфавитном порядке, либо просто в алфавитном порядке.

может кто-нибудь сказать мне, как сортировать список файлов?

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

3 ответов


это невозможно с помощью самого итератора. Я видел расширение к Iterator класс где-то на так, что сортировка, но смутно помню, что у него были проблемы с ним.

возможно, ответы на этот вопрос помощь, даже если они указывают далеко от итератора?

обновление: здесь является обманом на ваш вопрос с некоторыми ответами-по общему признанию, не так много, хотя!


доступно несколько вариантов, которые можно использовать для сортировки итератора тем или иным способом. Лучший вариант будет зависеть от того, как именно вы хотите манипулировать содержимым итератора, что вы хотите получить из итератора и действительно, сколько или мало итератора вы действительно хотите/нуждаетесь.

подходы будут отличаться; использование классов, таких как SplHeap (или Min, Max сорта), SplPriorityQueue (возможно для таких вещей, как размер файла) или просто накрутка ваш итератор в чем-то вроде ArrayObject, который может сортировать свое содержимое.

Я буду использовать SplHeap в качестве примера. Поскольку вы хотите упорядочить все содержимое RecursiveDirectoryIterator в алфавитном порядке, то что-то вроде следующего может быть использовано:

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;
}

порядок сортировки по алфавиту, смешивание файлов и папок:

./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

Sönke Ruempler есть отличное решение:

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;
        }
}

источник:http://www.ruempler.eu/2008/08/09/php-sortingiterator