tags:

views:

109

answers:

3
+1  Q: 

Recursing Properly

Hello,

I have several navigation related functions which I would like to have no depth limits. These generate CSS menus, breadcrumb trails and the like.

I am stumped as to how I would make the functions follow each path to depth or to root without explicit looping.

The following is a typical example where I want the topmost parent of a page. The topmost will have a value of zero in its parent field.

Here is the explicitly looped version:

    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

Anyone have advice or similar code or a tute link to help point the way?

TIA!!

jg

+8  A: 

It's easily expressable as a while loop:

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

$node now contains the topmost element.

Welbog
I think you reversed $node and $this (that is, it should be $this->retrieve("id = '$node->parent'"), but the idea is clear.
Stephan202
@Stephan202: You're right. Thanks for the comment. I corrected the answer.
Welbog
isn't $node = $this in the first place?
Petrunov
Thank you so much. I had a hunch there was an elegant solution to this but while() had not occurred to me!
jerrygarciuh
A: 

I haven't tested it, but it should work..:

function recurse( $pg )
{
    $parent_pg = $pg->retrieve( 'id = ' . $this->parent );

    if( $parent_pg->parent != 0 )
    {
        recurse( $parent_pg );
    }
    else
    {
        return $pg;
    }

}
Petrunov
Thanks Petrunov!
jerrygarciuh
+1  A: 

Welbog's answer is the nicest, but for completeness I'll add another recursive solution:

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

   return foo($this);
}
Stephan202