我正在寻找一种基于两个因素对对象数组进行排序的方法。 这是我目前的实施方案:
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
,但我不确定这与我现在正在做的事情有很大不同。
答案 0 :(得分:2)
您的排序逻辑可以简化为:
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所述,您可以通过在::compare($a, $b)
中实现上述逻辑来扩展SplHeap
,并在插入对象时对其进行排序。