代码之家  ›  专栏  ›  技术社区  ›  jerrygarciuh

正确递归

  •  1
  • jerrygarciuh  · 技术社区  · 15 年前

    我有几个导航相关的功能,我想没有深度限制。它们生成CSS菜单、面包屑路径等。

    我被难住了,我将如何使函数沿着每一条路径到达深度或根,而无需显式循环。

    下面是一个典型的示例,其中我希望页面的最顶层父级。最顶端的值在其值中为零 parent

    以下是显式循环版本:

    function topPg() {
        $p = $this->retrieve("id = '$this->parent'");
        if ($p->parent != 0) {
            $gp = $this->retrieve("id = '$p->parent'");
            if ($gp->parent != 0) {
                $ggp = $this->retrieve("id = '$gp->parent'");
                if ($ggp->parent != 0) {
                    $gggp = $this->retrieve("id = '$ggp->parent'");
                    // ad naseum
                } else {
                    return $ggp;
                }
            } else {
                return $gp;
            }
        } else {
            return $p;
        }
    } // func
    

    有人有建议或类似的代码或tute链接来帮助指明方向吗?

    3 回复  |  直到 13 年前
        1
  •  8
  •   Welbog    15 年前

    它很容易表达为while循环:

    $node = $this;
    while ($node->parent != 0) {
      $node = $this->retrieve("id = '$node->parent'");
    }
    

    $node 现在包含最上面的元素。

        2
  •  1
  •   Community Egal    7 年前

    Welbog's answer 是最好的,但为了完整性,我将添加另一个递归解决方案:

    function topPg() {
       function foo($p) {
         $gp = $this->retrieve("id = '$p->parent'");
         return ($gp->parent == 0) ? $p : foo($gp);
       }  
    
       return foo($this);
    }
    
        3
  •  0
  •   Petrunov    15 年前

    我还没有测试它,但它应该可以工作

    function recurse( $pg )
    {
        $parent_pg = $pg->retrieve( 'id = ' . $this->parent );
    
        if( $parent_pg->parent != 0 )
        {
            recurse( $parent_pg );
        }
        else
        {
            return $pg;
        }
    
    }