PHP RecursiveIteratorIterator:确定每个分支级别的第一项和最后一项 [英] PHP RecursiveIteratorIterator: Determining first and last item at each branch level

查看:103
本文介绍了PHP RecursiveIteratorIterator:确定每个分支级别的第一项和最后一项的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我扩展了Zend_View_Helper_Navigation_Menu,它使用RecursiveIteratorIterator遍历菜单树.我想确定的是我是在树中分支级别的第一项还是最后一项.

I have extended Zend_View_Helper_Navigation_Menu, and it uses a RecursiveIteratorIterator to iterate over the menu tree. What I want to be able to determine is whether I am on the first or last item for a branch level in the tree.

以下是我正在寻找的示例:

Here's an example of what I'm looking for:

  • 导航1(第一个)
    • 导航1.1(第一个和最后一个)
      • 导航1.1.1(第一个)
      • 导航1.1.2
      • 导航1.1.3(最后)
      • Nav 1 (first)
        • Nav 1.1 (first & last)
          • Nav 1.1.1 (first)
          • Nav 1.1.2
          • Nav 1.1.3 (last)
          • 导航2.1(第一个)
          • 导航2.2(最新)
          • 导航3.1(第一个)
          • 导航3.2(最后)

          其他信息

          • PHP版本5.2.13

          解决方案

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

          Within the foreach ($iterator as $page) loop two variables can be used to keep track of the depths, $depth and $prevDepth. A simple comparison conditional can then determine the first item in a branch level: if ($depth > $prevDepth).

          使用Zend_Navigation_Container对象创建RecursiveCachingIterator,然后使用该对象创建RecursiveIteratorIterator会添加hasNext()方法.

          Creating a RecursiveCachingIterator using the Zend_Navigation_Container object and then using that to create the RecursiveIteratorIterator adds the the hasNext() method.

          $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;
          }
          

          推荐答案

          使用RecursiveCachingIterator:

          Using RecursiveCachingIterator:

          $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;
              }
          }
          

          具有数组的另一种解决方案:

          Another solution with array:

          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 RecursiveIteratorIterator:确定每个分支级别的第一项和最后一项的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆