无限级分类 迭代法查看子孙树
function subtree($arr,$parent){
$subs = array();
$task = array($parent);
while(!empty($task)){
$flag = false; //$flag初始化为假
foreach($arr as $k=>$v){
if($v[‘parent’] == $parent){
$subs[] = $v;
$parent = $v[‘id’];
array_push($task,$v[‘id’]);
unset($arr[$k]); //为什么此处要用unset??????
$flag = true; //找到子栏目
}
}
if($flag == false){
array_pop($task);
$parent = end($task);
}
print_r($task);
}
return $subs;
}
回复讨论(解决方案)
当 foreach 执行过了 $arr[0] 后就销毁 $arr[0],执行了 $arr[1] 后就销毁 $arr[1]
如果不销毁的话 , while 循环执行到下一次时 后面的 foreach($arr as $k=>$v) 有会把$arr从头执行了
执行过的就清除,否则会重复执行。
举个例子就清楚了
$ar = array(
array(‘id’ => 1, ‘parent’] =>0),
array(‘id’ => 2, ‘parent’] =>1),
array(‘id’ => 3, ‘parent’] =>1),
);
subtree($ar, 1);
id=1 的节点有 id=2 和 id=3 的两个子节点
当找到 id=2 的节点后,如果不删去的话,下一轮查找就又会找到 id=2 的节点
从而出现死循环,显然这个 unset($arr[$k]); 是不得已而为之的,因为这个算法的思路有问题(他采用的是 深度优先算法,应该还有优化的余地)
而 广度优先算法 就要简单多了
function subtree($arr,$parent){
$subs = array();
$task = array($parent);
for($i=0;$i$v){
if($v[‘parent’] == $parent){
$subs[] = $v;
if(! in_array($v[‘id’], $task)) $task[] = $v[‘id’];
}
}
}
return $subs;
}
如果不unset,就会重复执行了。
当 foreach 执行过了 $arr[0] 后就销毁 $arr[0],执行了 $arr[1] 后就销毁 $arr[1]
如果不销毁的话 , while 循环执行到下一次时 后面的 foreach($arr as $k=>$v) 有会把$arr从头执行了
还有个问题,为什么要用$arr[$k],而不是$v[$k]
foreach($arr as $k=>$v)
相当于
$arr[$k] = $v;
要删除 $v 就是删除 $arr[$k] 了;
没有$v[$k] 这个。