$a = array(1,2,3,4,5,6,7);
$a2 = &$a; //引用foreach($a2 as $index =>$item){
echo "===outer start,index= $index ====<br />";
echo "\$a[",$index,'] =>',$item,"<br />";
echo 'count($a)=',count($a2).'<br />';
foreach ($a2 as $i => $val) {
echo "----inner start--- key=".$i." ----"; if($val==5){
echo "<br />";
array_splice($a2,$i,1);
//unset($a2[$i]);
echo 'array_splice($a,'.$i.',1),$val='.$val.' <br />';
echo 'count($a)=',count($a2).'<br />';
} echo "----inner end----<br />"; }
echo "\$a[",$index,'] =>',$item,"<br />";
echo 'count($a)=',count($a).'<br />';
echo "====outer end, index= $index ====<br />";
}print_r($a);
执行结果 ,为何$a2使用引用方式时, 在内层foreach 中的 array_splice()之后,不再执行外面的foreach===outer start,index= 0 ====
$a[0] =>1
count($a)=7
----inner start--- key=0 --------inner end----
----inner start--- key=1 --------inner end----
----inner start--- key=2 --------inner end----
----inner start--- key=3 --------inner end----
----inner start--- key=4 ----
array_splice($a,4,1),$val=5
count($a)=6
----inner end----
----inner start--- key=0 --------inner end----
----inner start--- key=1 --------inner end----
----inner start--- key=2 --------inner end----
----inner start--- key=3 --------inner end----
----inner start--- key=4 --------inner end----
----inner start--- key=5 --------inner end----
$a[0] =>1
count($a)=6
====outer end, index= 0 ====
Array ( [0] => 1 [1] => 2 [2] => 3 [3] => 4 [4] => 6 [5] => 7 )
array_splice($a,4,1) 默认重置里数组指针,因此内层重新执行了一遍循环如果改为 array_splice($a,4,1,true),内层就成了死循环,是何原理,我的理解,删掉一个数组元素,不就是少循环一次吗,为何出现这种情况
看到你的发布的树形数据程序了,我正是被这个事情难住,不知递归的应该怎么写,下面是我写的,我试过,传参用不用引用都没法实现,只能得到2层的属性数据,可否指点迷津
$mylist = array(array( 'parent_id'=>0,'id'=>1),
array( 'parent_id'=>0,'id'=>2),
array( 'parent_id'=>0,'id'=>3),
array( 'parent_id'=>2,'id'=>4),
array( 'parent_id'=>2,'id'=>5),
array( 'parent_id'=>3,'id'=>6),
array( 'parent_id'=>3,'id'=>7),
array( 'parent_id'=>4,'id'=>8),
array( 'parent_id'=>5,'id'=>9),
array( 'parent_id'=>5,'id'=>10)
); function _findChildren(&$p,&$list){ //数据立体化
foreach($list as $index=>$item){
if($item['parent_id']==$p['id']){
if(count($p['children'])==0){
$p['children']=array();
}
$p['children'][]=$item;
array_splice($list,$index,1);
//unset($list[$index]);
_findChildren($item,$list);
}
}
}
foreach($mylist as $index =>$item){
_findChildren($mylist[$index],$mylist);
}
array( 'parent_id'=>0,'id'=>2),
array( 'parent_id'=>0,'id'=>3),
array( 'parent_id'=>2,'id'=>4),
array( 'parent_id'=>2,'id'=>5),
array( 'parent_id'=>3,'id'=>6),
array( 'parent_id'=>3,'id'=>7),
array( 'parent_id'=>4,'id'=>8),
array( 'parent_id'=>5,'id'=>9),
array( 'parent_id'=>5,'id'=>10)
);function _findChildren($list, $p){ //数据立体化
$r = array();
foreach($list as $id=>$item){
if($item['parent_id'] == $p) {
$r[$id] = $item;
$r[$id]['children'][] = _findChildren($list, $item['id']);
}
}
return $r;
} print_r(_findChildren($mylist, 0));
Array
(
[0] => Array
(
[parent_id] => 0
[id] => 1
[children] => Array
(
[0] => Array
(
) ) ) [1] => Array
(
[parent_id] => 0
[id] => 2
[children] => Array
(
[0] => Array
(
[3] => Array
(
[parent_id] => 2
[id] => 4
[children] => Array
(
[0] => Array
(
[7] => Array
(
[parent_id] => 4
[id] => 8
[children] => Array
(
[0] => Array
(
) ) ) ) ) ) [4] => Array
(
[parent_id] => 2
[id] => 5
[children] => Array
(
[0] => Array
(
[8] => Array
(
[parent_id] => 5
[id] => 9
[children] => Array
(
[0] => Array
(
) ) ) [9] => Array
(
[parent_id] => 5
[id] => 10
[children] => Array
(
[0] => Array
(
) ) ) ) ) ) ) ) ) [2] => Array
(
[parent_id] => 0
[id] => 3
[children] => Array
(
[0] => Array
(
[5] => Array
(
[parent_id] => 3
[id] => 6
[children] => Array
(
[0] => Array
(
) ) ) [6] => Array
(
[parent_id] => 3
[id] => 7
[children] => Array
(
[0] => Array
(
) ) ) ) ) ))
如果不想要空子树function _findChildren($list, $p){ //数据立体化
$r = array();
foreach($list as $id=>$item){
if($item['parent_id'] == $p) {
$r[$id] = $item;
if($t = _findChildren($list, $item['id']) )
$r[$id]['children'][] = $t;
}
}
return $r;
} Array
(
[0] => Array
(
[parent_id] => 0
[id] => 1
) [1] => Array
(
[parent_id] => 0
[id] => 2
[children] => Array
(
[0] => Array
(
[3] => Array
(
[parent_id] => 2
[id] => 4
[children] => Array
(
[0] => Array
(
[7] => Array
(
[parent_id] => 4
[id] => 8
) ) ) ) [4] => Array
(
[parent_id] => 2
[id] => 5
[children] => Array
(
[0] => Array
(
[8] => Array
(
[parent_id] => 5
[id] => 9
) [9] => Array
(
[parent_id] => 5
[id] => 10
) ) ) ) ) ) ) [2] => Array
(
[parent_id] => 0
[id] => 3
[children] => Array
(
[0] => Array
(
[5] => Array
(
[parent_id] => 3
[id] => 6
) [6] => Array
(
[parent_id] => 3
[id] => 7
) ) ) ))
$a2 = &$a; //引用
foreach ( $a2 as $index => $item ) {
echo "===outer start,index= $index ====<br />";
echo "\$a[", $index, '] =>', $item, "<br />";
echo 'count($a)=', count ( $a2 ) . '<br />';
foreach ( $a2 as $i => $val ) {
//echo '<pre>';debug_zval_dump($a2);echo '<br />';
echo "----inner start--- key={$i} --value= {$val} -- ----";
if ($val == 5) {
echo "<br />";
array_splice ( $a2, $i, 1 );
//unset($a2[$i]);
echo 'array_splice($a,' . $i . ',1),$val=' . $val . ' <br />';
echo 'count($a)=', count ( $a2 ) . '<br />';
}
echo "----inner end----<br />";
}
reset($a2);
echo "\$a[", $index, '] =>', $item, "<br />";
echo 'count($a)=', count ( $a ) . '<br />';
echo "====outer end, index= $index ====<br />";
}print_r ( $a );估计是要在第二层的foreach外面再加reset($a2),可以看到可以运行了。因为此时的$a2已经指向末尾了。
我在_findChildren里用array_splice是想把已经找到父节点的元素copy到父节点的‘children’里面,然后删掉那个节点,继续在原数组递归处理,逐步减少递归次数像这种情况,一定要另建数组来保存吗
你是说由于引用的原因,内层的循环会与外层的循环会共享索引吗,但是看起来不像啊,
如果不使用array_splice()的话,外层还是会循环下去的