PHP 递归迭代器迭代器 : Determining first and last item at each branch level

标签 php zend-framework recursion zend-navigation

我扩展了 Zend_View_Helper_Navigation_Menu,它使用 RecursiveIteratorIterator 来迭代菜单树。我希望能够确定的是我是在树中分支级别的第一项还是最后一项。

这是我正在寻找的示例:

  • 导航 1(第一个)
    • Nav 1.1(第一个和最后一个)
      • 导航 1.1.1(第一)
      • 导航 1.1.2
      • 导航 1.1.3(最后)
  • 导航 2
    • 导航 2.1(第一)
    • 导航 2.2(最后)
  • 导航 3(最后)
    • 导航 3.1(第一)
    • 导航 3.2(最后)

附加信息

  • PHP 版本 5.2.13

解决方案

foreach ($iterator as $page) 循环中,可以使用两个变量来跟踪深度,$depth$prevDepth。然后,一个简单的比较条件就可以确定分支级别中的第一项:if ($depth > $prevDepth)

使用 Zend_Navigation_Container 对象创建一个 RecursiveCachingIterator,然后使用它来创建 RecursiveIteratorIterator 添加 hasNext() 方法。

$rci = new RecursiveCachingIterator($container, CachingIterator::FULL_CACHE);
$iterator = new RecursiveIteratorIterator($rci,
                    RecursiveIteratorIterator::SELF_FIRST);
/* snip */
$prevDepth = -1;
foreach ($iterator as $page) {
    $depth = $iterator->getDepth();
    /* snip */
    if ($depth > $prevDepth) {
        // first branch item
    }
    /* snip */
    if (!$iterator->hasNext()) {
        // last branch item
    }
    /* snip */
    $prevDepth = $depth;
}

最佳答案

使用递归缓存迭代器:

$rdi = new RecursiveDirectoryIterator('.');
$rci = new RecursiveCachingIterator($rdi, CachingIterator::FULL_CACHE); 
$rii = new RecursiveIteratorIterator($rci, RecursiveIteratorIterator::SELF_FIRST);

foreach ($rii as $file) {
    if ($file->isDir()) {
        echo $file->getFilename() . PHP_EOL;
    }
    elseif (!$rii->hasNext()) {
        echo $file->getFilename() . PHP_EOL;
    }
    elseif (count($rii->getCache()) == 1) {
        echo $file->getFilename() . PHP_EOL;
    }
}

另一个数组解决方案:

function buildTree(RecursiveDirectoryIterator $iterator) {
    $tree = array();
    foreach ($iterator as $fileinfo) {
        if ($fileinfo->isDir()) {
            $tree[$fileinfo->getFilename()] = buildTree($iterator->getChildren());
        } else {
            $tree[$fileinfo->getFilename()] = $fileinfo->getFilename();
        }
    }
    return $tree;
}

function filterTree(array $tree) {
    foreach ($tree as $key => $value) {
        if (is_array($value)) {
            $tree[$key] = filterTree($value);
        } elseif (reset($tree) !== $value && end($tree) !== $value) {
            unset($tree[$key]);
        }
    }
    return $tree;
}

print_r(filterTree(buildTree(new RecursiveDirectoryIterator('.'))));

关于PHP 递归迭代器迭代器 : Determining first and last item at each branch level,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4348100/

相关文章:

php - jQuery 中的类和子字符串?

php - Mysql 查询 - 使用连接/联合等

php - 使用 TemplateProcessor 使用 PHPWord 在 .docx 中添加图像

php - 可以查看助手读取请求

php - 使用递归构建动态 super 菜单?

php - Mysql 选择多个查询

php - 保存网页时图像未保存!

zend-framework - 多选,设置默认选定值

javascript - 递归循环直到我们完成对象 [JS]

c - 为什么return语句不结束c中的递归函数?