我不习惯递归函数,我不明白如何正确退出函数。
我尝试从数据库中的父项(使用Laravel)中识别子项列表(孙子等)。
public function getChildren($parentId, $allChildrenArray = Array()){
$children = DB::table('myTable')->where('parent',$parentId)->get();
if (sizeof($children)>0){
foreach ($children as $child) {
array_push($allChildrenArray,array($child->slug, $child->id));
MyController::getChildren($child->id, $allChildrenArray);
}
}else{
// var_dump($allChildrenArray); displays a proper array
return $allChildrenArray;
}
}
我对此有两个问题。
如果我显示var_dump($allChildrenArray)
,则显示一个似乎正常的数组。
但是,如果我尝试从其他函数显示它,我会得到null
...
public function doStuff($itemId){
$allChildrenArray = MyController::getChildren($itemId);
var_dump($allChildrenArray); // displays null
}
答案 0 :(得分:2)
首先,您应该将助手放在控制器之外:)
更重要的是:要理解递归,它有助于逐步处理,当你进行递归时,假设我们假设它正在做它应该做的事情,然后再回到那里。
让我们这样开始:
/**
* Returns the children for a given parent
* @param int $parentId
* @return array
*/
public function getChildren($parentId){
$allChildrenArray = array();
$children = DB::table('myTable')->where('parent',$parentId)->get();
foreach ($children as $child) {
array_push($allChildrenArray, array($child->slug, $child->id));
// Here should be the recursion later
}
// var_dump($allChildrenArray); displays a proper array
return $allChildrenArray;
}
现在,如果您查看此功能,您将看到它适用于第一级。很容易说,当你通过给定父级的子节点时,如果要添加递归,则需要获取这些后代。
/**
* Returns the children recursively for a given parent
* @param int $parentId
* @return array
*/
public function getChildren($parentId){
$allChildrenArray = array();
$children = DB::table('myTable')->where('parent',$parentId)->get();
foreach ($children as $child) {
array_push($allChildrenArray, array($child->slug, $child->id));
// get descendants of child
$furtherDescendants = $this->getChildren($child->id);
// add them to current list
foreach ($furtherDescendants as $desc) {
$allChildrenArray[] = $desc; // or use arraypush or merge or whatever
}
}
// var_dump($allChildrenArray); displays a proper array
return $allChildrenArray;
}
现在发生的事情是,当你到达第一个孩子时,新的getChildren函数运行将以该孩子的id作为父id开始。如果没有它的子项,那么它将返回一个空数组,否则它将为该子项添加信息,然后为孙子的id启动一个新的运行作为父ID和...
如果传递数组,可以节省一些内存,但在这种情况下,您需要将其作为参考。此外,当您首先调用此方法时,您需要将变量作为将填充的输入传递。
/**
* Returns the children recursively for a given parent
* @param int $parentId
* @param &array $children
*/
public function getChildren($parentId, &$allChildrenArray) {
$children = DB::table('myTable')->where('parent',$parentId)->get();
foreach ($children as $child) {
array_push($allChildrenArray, array($child->slug, $child->id));
// get descendants of child
$this->getChildren($child->id, $allChildrenArray);
}
// var_dump($allChildrenArray); displays a proper array
return; // nothing to return, children info added to variable passed by reference
}
...
$kids=array();
$this->getChildren($parentId, $kids);
var_dump($kids)
请确保不要混淆两种不同的解决方案。
当给定父母没有孩子时,退出条件就是这种情况。在这种情况下,foreach将不会启动,因此不会再进行进一步的递归调用。然而,这只意味着退出该分支。