我正在寻找一种基于两个因素对对象数组进行排序的方法。这是我目前的usort实现:
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
}
});正如您可能已经猜到的,对象表示文件,但是在本例中,只有->getName和->isDirectory方法是相关的。
我创建的这个示例确实有效,但是我在一个包含9000个文件的集合上测试了它,仅这个块就将一般进程的时间从1秒增加到了大约3秒。
它所做的排序相当简单:
我正在寻找一种方法来改进它,或者找到一个替代方案。
如果是任何人感兴趣的,这就是$contents数组的来源:
$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;然而,这个过程只需很少的时间,我很有兴趣发现排序可以在读取目录期间完成。
附带注意,我读到我可以通过扩展DirectoryIterator并执行比较来使用它,但我不确定这与我现在正在做的事情有很大不同。
发布于 2014-06-11 14:28:38
您的排序逻辑可以简化为以下内容:
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());此外,正如Mark提到的那样,您可以通过在SplHeap中实现上述逻辑来扩展::compare($a, $b),并在插入对象时对对象列表进行排序。
https://stackoverflow.com/questions/24165247
复制相似问题