4
回答
php 数组无限极子分类问题
百度AI开发者大赛带你边学边开发,赢100万奖金,加群:418589053   
用PHP做项目,经常要用到无限极分类,需要做一个查找数组除子分类外的元素,我做的函数有点问题.
//返回除传递id子分类的函数
function unlimited_notchild(&$arr,$pid_name,$id=0){
    foreach ($arr as $k=>$v) {
        if($v["$pid_name"]==$id){
            unlimited_notchild($arr,$pid_name,$v['id']);
            unset($arr[$k]);
        }
    }
    return $arr;
}
$item = array(
     1 => array('id' => 1, 'pid' => 0, 'name' => '内蒙古'),
     2 => array('id' => 2, 'pid' => 0, 'name' => '浙江省'),
     3 => array('id' => 3, 'pid' => 1, 'name' => '鄂尔多斯'),
     4 => array('id' => 4, 'pid' => 3, 'name' => '东胜区'),
     5 => array('id' => 5, 'pid' => 1, 'name' => '呼和浩特'),
     6 => array('id' => 6, 'pid' => 2, 'name' => '宁波市'),
 );
$it=unlimited_notchild($item,"pid",1);
var_dump($it);

返回的结果:
array (size=4)
  1 => 
    array (size=3)
      'id' => int 1
      'pid' => int 0
      'name' => string '内蒙古' (length=9)
  2 => 
    array (size=3)
      'id' => int 2
      'pid' => int 0
      'name' => string '浙江省' (length=9)
  5 => 
    array (size=3)
      'id' => int 5
      'pid' => int 1
      'name' => string '呼和浩特' (length=12)

  6 => 
    array (size=3)
      'id' => int 6
      'pid' => int 2
      'name' => string '宁波市' (length=9)

1--红颜色的,不应该存在吧,我的程序逻辑哪块出问题了.
2--数组键值是乱的,这个怎么弄了.
 3-- 我想把自身也去掉
请高手赐教,谢谢
PHP
举报
manbudezhu
发帖于2年前 4回/370阅
共有4个答案 最后回答: 2年前

避免在循环中使用unset

function unlimited_notchild(&$arr,$pid_name,$id=0){
    foreach ($arr as $k=>$v) {
        if($v["$pid_name"]==$id){
            $arr[$k] = null; //不直接删除 设置为空
            unlimited_notchild($arr,$pid_name,$v['id']);
        }
    }
    /* array_filter 清理空值 */
    /* array_values 取数组值 用处是重置下标 */
    return array_values(array_filter($arr));
}
$item = array(
    1 => array('id' => 1, 'pid' => 0, 'name' => '内蒙古'),
    2 => array('id' => 2, 'pid' => 0, 'name' => '浙江省'),
    3 => array('id' => 3, 'pid' => 1, 'name' => '鄂尔多斯'),
    4 => array('id' => 4, 'pid' => 3, 'name' => '东胜区'),
    5 => array('id' => 5, 'pid' => 1, 'name' => '呼和浩特'),
    6 => array('id' => 6, 'pid' => 2, 'name' => '宁波市'),
);
$it = unlimited_notchild($item,"pid",1);
var_dump($it);



<?php
header('Content-Type: text/plain; charset=utf-8');
function tree(array $arr, $pid = 0, $i = '', array &$children = array()) {
	foreach ($arr as $ele) {
		if ($ele['pid'] === $pid) { //递归条件
			$indent = ($ele['pid'] === 0) ? $i : '__'.$i;
			//echo $indent.$ele['id'].':'.$ele['name']."\n"; //输出树形结构
			$children[] = $ele['id'];
			tree($arr, $ele['id'], $indent, $children); //递归
		}
	}
}
function foo(array $arr, $id) {
	$tmp = array($id);
	tree($arr,$id,'',$tmp);
	foreach($arr as $k => $v) {
		foreach($tmp as $v1) {
			if($v['id'] == $v1) {
				unset($arr[$k]);
			}
		}
	}
	return $arr;
}
$arr = array(
	1 => array('id' => 1, 'pid' => 0, 'name' => '内蒙古'),
	2 => array('id' => 2, 'pid' => 0, 'name' => '浙江省'),
	3 => array('id' => 3, 'pid' => 1, 'name' => '鄂尔多斯'),
	4 => array('id' => 4, 'pid' => 3, 'name' => '东胜区'),
	5 => array('id' => 5, 'pid' => 1, 'name' => '呼和浩特'),
	6 => array('id' => 6, 'pid' => 2, 'name' => '宁波市'),
);
var_export(foo($arr,1)); //删除id为1的节点及其子节点

输出:
array (
  2 =>
  array (
    'id' => 2,
    'pid' => 0,
    'name' => '浙江省',
  ),
  6 =>
  array (
    'id' => 6,
    'pid' => 2,
    'name' => '宁波市',
  ),
)

附:可见内蒙古的节点被删除了,数组对应的树形结构
1:内蒙古
__3:鄂尔多斯
____4:东胜区
__5:呼和浩特
2:浙江省
__6:宁波市

引用来自“xioxin”的评论

避免在循环中使用unset

function unlimited_notchild(&$arr,$pid_name,$id=0){
    foreach ($arr as $k=>$v) {
        if($v["$pid_name"]==$id){
            $arr[$k] = null; //不直接删除 设置为空
            unlimited_notchild($arr,$pid_name,$v['id']);
        }
    }
    /* array_filter 清理空值 */
    /* array_values 取数组值 用处是重置下标 */
    return array_values(array_filter($arr));
}
$item = array(
    1 => array('id' => 1, 'pid' => 0, 'name' => '内蒙古'),
    2 => array('id' => 2, 'pid' => 0, 'name' => '浙江省'),
    3 => array('id' => 3, 'pid' => 1, 'name' => '鄂尔多斯'),
    4 => array('id' => 4, 'pid' => 3, 'name' => '东胜区'),
    5 => array('id' => 5, 'pid' => 1, 'name' => '呼和浩特'),
    6 => array('id' => 6, 'pid' => 2, 'name' => '宁波市'),
);
$it = unlimited_notchild($item,"pid",1);
var_dump($it);



这个挺好的,但是自身好像没有被排除.如何在数组中排除自身了(这里是id值为1的元素)
--- 共有 1 条评论 ---
xioxin在循环里加上 if($v['id'] == $id){ $arr[$k] = null; } 2年前 回复

无限分类其实就是树模型,有不同的做法,具体看自己的业务情况

具体请参考 -> http://stackoverflow.com/questions/4048151/what-are-the-options-for-storing-hierarchical-data-in-a-relational-database


顶部