使用PHP获取最深的文件路径

时间:2012-04-14 07:12:28

标签: php arrays path

有没有人知道如何从具有文件路径的数组中获取最深路径的元素?如果这听起来很奇怪,想象下面的数组:

/a/b
/a
/1/2/3/4
/1/2
/1/2/3/5
/a/b/c/d/e

我想要获得的是:

/1/2/3/4
/1/2/3/5
/a/b/c/d/e

想知道最快的方法是什么,而不必一遍又一遍地遍历整个数组。语言是PHP(5.2)。

3 个答案:

答案 0 :(得分:1)

$aPathes = array(
    '/a/b',
    '/a',
    '/1/2/3/4',
    '/1/2',
    '/1/2/3/5',
    '/a/b/c/d/e'
);

function getDepth($sPath) {
    return substr_count($sPath, '/');
}
$aPathDepths = array_map('getDepth', $aPathes);
arsort($aPathDepths);
foreach ($aPathDepths as $iKey => $iDepth) {
    echo $aPathes[$iKey] . "\n";
}

另见this example

=== UPDATE ===

$aUsed = array();
foreach ($aPathes as $sPath) {
    foreach ($aUsed as $iIndex => $sUsed) {
        if (substr($sUsed, 0, strlen($sPath)) == $sPath || substr($sPath, 0, strlen($sUsed)) == $sUsed) {
            if (strlen($sUsed) < strlen($sPath)) {
                array_splice($aUsed, $iIndex, 1);
                $aUsed[] = $sPath;
            }
            continue 2;
        }
    }
    $aUsed[] = $sPath;
}

另见this example

答案 1 :(得分:1)

在您的澄清之后,这是一个可以做到这一点的功能。它保留了一个“最深路径”的数组,并将每条路径与它进行比较。最好的情况是O(n)(如果所有路径都是最大路径的子路径),最坏情况是O(n 2 )(如果所有路径完全不同)。

请注意continue 2表示“继续外循环”。

<?php

function getDeepestPaths($array)
{
    $deepestPaths = array();
    foreach ($array as $path)
    {
        $pathLength = strlen($path);
        // look for all the paths we consider the longest
        // (note how we're using references to the array members)
        foreach ($deepestPaths as &$deepPath)
        {
            $deepPathLength = strlen($deepPath);
            // if $path is prefixed by $deepPath, this means that $path is
            // deeper, so we replace $deepPath with $path
            if (substr($path, 0, $deepPathLength) == $deepPath)
            {
                $deepPath = $path;
                continue 2;
            }
            // otherwise, if $deepPath is prefixed by $path, this means that
            // $path is shallower; so we should stop looking
            else if (substr($deepPath, 0, $pathLength) == $path)
            {
                continue 2;
            }
        }
        // $path matches nothing currently in $deepestPaths, so we should
        // add it to the array
        $deepestPaths[] = $path;
    }
    return $deepestPaths;
}

$paths = array('/a/b', '/a', '/1/2/3/4', '/1/2', '/1/2/3/5', '/a/b/c/d/e');
print_r(getDeepestPaths($paths));

?>

如果您的文件夹名称不以斜杠结尾,则您需要在两个if中进行额外检查:更深路径中前缀旁边的字符是斜杠,否则类似/foo/bar的路径将被视为比/foo/b更“深入的路径”(并将替换它)。

if (substr($path, 0, $deepPathLength) == $deepPath && $path[$deepPathLength] == '/')
if (substr($deepPath, 0, $path) == $path && $deepPath[$path] == '/')

答案 2 :(得分:0)

如果你能保证&#34;拼写&#34;总是一样的(即:&#34; / a / bc / d&#34; vs. / a / b \ / c / d)然后你应该能够做一些简单的字符串比较,看看是否有一个字符串完全包含在另一个中。如果这是真的丢弃字符串。 请注意,您需要在两个方向进行比较。