前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >无限分类之子孙树与家谱树实现

无限分类之子孙树与家谱树实现

作者头像
切图仔
发布2022-09-14 15:21:06
5070
发布2022-09-14 15:21:06
举报
文章被收录于专栏:生如夏花绚烂

无限分类在日常开发中很常见至少对于PHP程序员来说,如网站常见的商品分类、面包屑、省市联动、新闻分类等等,一个栏目又包含很多个子栏目子栏目又包含很多子栏目...。 这里介绍无限分类的子孙树与家谱树实现。

子孙数

子孙树是用递归查找栏目的所有子类,以及子类的子类,子类的子类的子类。

1.数据准备

代码语言:javascript
复制
$arr = [
    ['id'=>1,'name'=>'四川','parent'=>0],
    ['id'=>2,'name'=>'广东','parent'=>0],
    ['id'=>3,'name'=>'成都','parent'=>1],
    ['id'=>4,'name'=>'德阳','parent'=>1],
    ['id'=>5,'name'=>'南充','parent'=>1],
    ['id'=>6,'name'=>'深圳','parent'=>2],
    ['id'=>7,'name'=>'华阳县','parent'=>3],
    ['id'=>8,'name'=>'金牛区','parent'=>3],
    ['id'=>9,'name'=>'营山县','parent'=>5],
    ['id'=>10,'name'=>'嘉陵区','parent'=>5],
    ['id'=>11,'name'=>'南部县','parent'=>5],
    ['id'=>12,'name'=>'罗江区','parent'=>4],
    ['id'=>13,'name'=>'旌阳区','parent'=>4],
    ['id'=>14,'name'=>'南山区','parent'=>6],
    ['id'=>15,'name'=>'盐田区','parent'=>6],
    ['id'=>16,'name'=>'星火镇','parent'=>9],
    ['id'=>17,'name'=>'七涧乡','parent'=>16],
];

我们将所有地区都放在一个数组,他们之间的关系依靠parent绑定,顶级的地区parent等于0 案例:查找某地区以及该地区管辖的子地区

代码语言:javascript
复制
function subtree($arr,$id){
    static $subs = [];
    foreach($arr as $v){
        //查找一级
        if($v['parent']==$id){
            $subs[] = $v;
            subtree($arr,$v['id']);
        }
    }
    return $subs;
}
print_r(subtree($arr,1));

结果如下

代码语言:javascript
复制
Array
(
    [0] => Array
        (
            [id] => 3
            [name] => 成都
            [parent] => 1
        )

    [1] => Array
        (
            [id] => 7
            [name] => 华阳县
            [parent] => 3
        )

    [2] => Array
        (
            [id] => 8
            [name] => 金牛区
            [parent] => 3
        )

    [3] => Array
        (
            [id] => 4
            [name] => 德阳
            [parent] => 1
        )

    [4] => Array
        (
            [id] => 12
            [name] => 罗江区
            [parent] => 4
        )

    [5] => Array
        (
            [id] => 13
            [name] => 旌阳区
            [parent] => 4
        )

    [6] => Array
        (
            [id] => 5
            [name] => 南充
            [parent] => 1
        )

    [7] => Array
        (
            [id] => 9
            [name] => 营山县
            [parent] => 5
        )

    [8] => Array
        (
            [id] => 16
            [name] => 星火镇
            [parent] => 9
        )

    [9] => Array
        (
            [id] => 17
            [name] => 七涧乡
            [parent] => 16
        )

    [10] => Array
        (
            [id] => 10
            [name] => 嘉陵区
            [parent] => 5
        )

    [11] => Array
        (
            [id] => 11
            [name] => 南部县
            [parent] => 5
        )

)

所有地区被打印出来,并且正常分类,我们还可以将其格式输出只需要给某个地区添加级别标识即可

代码语言:javascript
复制
function subtree($arr,$id,$lev=1){
    static $subs = [];
    foreach($arr as $v){
        //查找一级
        if($v['parent']==$id){
            $v['lev'] = $lev;
            $subs[] = $v;
            subtree($arr,$v['id'],$lev+1);
        }
    }
    return $subs;
}

$tree = subtree($arr,1);
foreach ($tree as $v) {
    echo str_repeat('----',$v['lev']).$v['name']."<br />";
}

输出如下

代码语言:javascript
复制
----成都
--------华阳县
--------金牛区
----德阳
--------罗江区
--------旌阳区
----南充
--------营山县
------------星火镇
----------------七涧乡
--------嘉陵区
--------南部县
家谱树

家谱树利用递归查找子栏目的父级栏目,父级栏目的父级栏目,父级栏目的父级栏目的父级栏目... 家谱树的应用也很广泛如常见的面包屑导航

案例:查找某地区的父栏目的栏目的父栏目....

代码语言:javascript
复制
function basetree($arr,$id){
    static $fathers = [];
    foreach ($arr as $v) {
        if($v['id']==$id){
            //判断是否继续寻找父栏目
            if($v['parent']>0){
                basetree($arr,$v['parent']);
            }
            $fathers[] = $v;
            
        }
    }
    return $fathers;

}
print_r(basetree($arr,16));

返回结果

代码语言:javascript
复制
Array
(
    [0] => Array
        (
            [id] => 1
            [name] => 四川
            [parent] => 0
        )

    [1] => Array
        (
            [id] => 5
            [name] => 南充
            [parent] => 1
        )

    [2] => Array
        (
            [id] => 9
            [name] => 营山县
            [parent] => 5
        )

    [3] => Array
        (
            [id] => 16
            [name] => 星火镇
            [parent] => 9
        )

)

迭代家谱树

代码语言:javascript
复制
function basetree($arr,$id){
   $fathers = [];
   while ($id!=0) {
       foreach ($arr as $v) {
           if($v['id']==$id){
               $fathers[] = $v;
               $id = $v['parent'];
               break;
           }
       }
       
   }
   
   return $fathers;

}
print_r(basetree($arr,16));

返回结果与上面一样不过性能比递归要高

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020-08-11 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 子孙数
  • 家谱树
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档