PHP:usort文件/速度

时间:2014-06-11 14:16:18

标签: php arrays file sorting directory

我正在寻找一种基于两个因素对对象数组进行排序的方法。 这是我目前的实施方案:

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,但我不确定这与我现在正在做的事情有很大不同。

1 个答案:

答案 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,并在插入对象时对其进行排序。