I am looking for a way to sort an array of objects based on two factors. This is my current usort implementation:
usort($contents, function($a, $b) {
$aN = $a->getName();
$bN = $b->getName();
$aD = $a->isDirectory();
$bD = $b->isDirectory();
switch(true) {
case $aD && !$bD: return -1;
case !$aD && $bD: return +1;
default:
return strcmp($aN, $bN); // Edited
}
});
As you might have guessed, the objects represent files, however for this example, only the ->getName
and ->isDirectory
methods are relevant.
This example I have create does work, however I tested it on a collection of 9000 files, and this block alone increased the time of the general process from 1 second to around 3.
The sorting it is doing is fairly simple:
I am looking for a way to improve it, or find an alternative.
If it is to anyones interest, this is the source of the $contents
array:
$path = $this->compute($path);
$dir = opendir($path);
$contents = array();
while(false !== $name = readdir($dir)) {
if($name == '.' || $name == '..') {
continue;
}
$contents[] = new LocalFile($this->directory, sprintf('%s/%s', $path, $name));
}
return $contents;
However this process takes very little time, I would be interested to discover that sorting can be accomplishing during the reading of a directory.
Side note, I have read I can use DirectoryIterator
by extending it and performing comparisons, but I am not sure that is a lot different to what I am doing right now.
Your sorting logic could be simplified to just this:
if (($a_isdir = $a->isDirectory()) != $b->isDirectory()) {
// either a is directory and b is not, or the other way around
return $a_isdir ? -1 : 1;
}
// a and b are either both directories or files
// compare normally
return strcmp($a->getName(), $b->getName());
Additionally, as mentioned by Mark, you can extend SplHeap
by implementing the above logic inside ::compare($a, $b)
and have the list of objects sorted as you insert them.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.