简体   繁体   中英

Recursion Result stack

What is the cleanest way to pass the result of this recursive function back out?

function recursion_trigger($input, $count = 0){

        if(!empty($input)){
                array_pop($input);
                $count++;
                if(!empty($input)){
                recursion_trigger($input,$count);
                }
        }

echo $count;
return $count;


}

At the moment it is returning the top most call which is of course one.

/////// as an additional question this is the full function can you use tail recursion here? The output is an array that I am constructing as I pass through the values.

<?php    
//Page best viewed from page source 

 //Takes an array of objects that have ID and Parent and organizes the tree into an array representing a set of objectID's by depth 

 // poor spelling ahead =P

function level_keys($array,$depth=-1,$level=0,$output=null){

// initialize the functions parameters run once at start and not in subsequent self calls

if($level == 0 && $depth != 0){
    $output[][]=0;
    $level++;
        foreach($array as $key=>$node){
            if($node->parent==0){
                $output[$level][] = $node->id;
                unset($array[$key]);
            }
        }
            unset($key); unset($node);
$level++;
$depth--;

}

// set recursion loop and run main part of function

if (  !empty($array) && $depth != 0){

    echo 'depth:'.$depth."\n";

    foreach($output[$level-1] as $parent){  
        foreach($array as $key=> $child){
            if( $parent == $child->parent){
            $output[$level][] = $child->id;
            unset($array[$key]);
            }
        }
    }
        unset($id); unset($parent); unset($key); unset($child);
$depth--;
$level++;
        if(!empty($array) && $depth !=0 ){
            // make sure to pass the output back out to the top most level
            $output = level_keys($array,$depth,$level,$output,$depth_at);
        }
}

return $output;

}
?>

You should update your $count variable with the return value of recursion_trigger

if(!empty($input)){
    $count = recursion_trigger($input,$count);
}

EDIT:

Hopefully the following will help you visualise how it's working:

recursion_trigger ( array("This", "Is", "A", "Sample"), 0)
  recursion_trigger ( array("This", "Is", "A"), 1)
    recursion_trigger ( array("This", "Is"), 2)
      recursion_trigger ( array("This"), 3)
        recursion_trigger ( array(), 4)

The way you were thinking probably was along the lines that $count was persistent, whereas it isn't because of call by value. This version, using references, also works.

function recursion_trigger($input, &$count = 0){

        if(!empty($input)){
                array_pop($input);
                $count++;
                if(!empty($input)){
                recursion_trigger($input,$count);
                }
        }

echo $count;
return $count;


}

I guess what you really need is not to count the number of elements in an array.

When you do recursive functions like this one, it is good for performance if they are tail-recursive (in fact, I'm not sure php has this optimisation, I hope so). Here you have $count that can serve as accumulator but don't use it.

function recursion_trigger ($input, $count = 0)
{
  if (!empty($input)) {
    array_pop($input);
    return recursion_trigger($input, $count + 1);
  }
  return $count;
}

This way it works and is tail recursive :-).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM