php-ml自动分类,PHP实现无限级分类(递归+引用)

原始数据

数据库

0fbe2f982a03

原始数据

打印到页面

0fbe2f982a03

原始数据

递归

递归的思路就是【找儿子】,也就是循环所有数据,找到每条数据的所有儿子、儿子的儿子、儿子的儿子的儿子....,首先我们知道要找test1的儿子就是找所有pid为1的数据,于是遍历整个数组找到了test1-1和test1-2;然后还要分别找test1-1和test1-2的儿子,就这样一直找下去,由于每次找儿子的方法都是一样的,就是遍历所有数据(除开自己的长辈,因为长辈不可能是儿孙),找出符合条件的,唯一不同的就是每次找儿子的爹不一样,代码如下:

function getChild($data, $id = 0)

{

//初始化儿子

$child = [];

//循环所有数据找$id的儿子

foreach ($data as $key => $datum) {

//找到儿子了

if ($datum['pid'] == $id) {

//保存下来,然后继续找儿子的儿子

$child[$datum['id']] = $datum;

//先去掉自己,自己不可能是自己的儿孙

unset($data[$key]);

//递归找,并把找到的儿子放到一个child的字段中

$child[$datum['id']]['child'] = $this->getChild($data, $datum['id']);

}

}

return $child;

}

运行结果:

0fbe2f982a03

递归运行结果

引用

引用确实是一个非常巧妙的方法,也不用像递归那样循环那么多次,思路就是首先把所有数据以id为索引重新排列,排列之后长这个样子:

0fbe2f982a03

重排之后的数据

然后重点来啦!!!然后只需要找到根节点,也就是pid是0的三条数据,把它们放到一个全新的数组中,注意:这里的放并不是简单的赋值,而是引用之前的地址。这两者有什么不同呢,这里简单几个例子说明一下:

function test(){

$a=1;

$b=$a; //赋值

$b1=&$a;//赋址

$a=2;

dump('$b的值是:'.$b);

dump('$b1的值是:'.$b1);

}

最开始$a初始化为1,把$a的值(也就是1)赋给变量$b,然后把$a的地址(内存地址)赋给$b1,然后改变$a的值,再查看$b和$b的值。结果如下:

0fbe2f982a03

传值和传址的区别

我们发现$b的值还是1,而$b1的值却跟随着$a的改变而改变了,这就是因为$b保存的是$a的地址,无论$a怎么变他们的值都会保持一致。

回到我们之前的问题上来,我们用新的数组保存了根节点的地址,后面无论根节点怎么变我们的新数组都会和变化过后的数据保持一致;那么不是根节点的数据怎么处理呢,我们这里可以把它的地址放到他爹的儿子节点当中,这样的话就是一层层引用,最后所有的数据都被新数组引用了。

说了这么多,代码如下:

function getChild($data)

{

$tree = [];

$newData = [];

//循环重新排列

foreach ($data as $datum) {

$newData[$datum['id']] = $datum;

}

foreach ($newData as $key => $datum) {

if ($datum['pid'] > 0) {

//不是根节点的将自己的地址放到父级的child节点

$newData[$datum['pid']]['child'][] = &$newData[$key];

} else {

//根节点直接把地址放到新数组中

$tree[] = &$newData[$datum['id']];

}

}

return $tree;

}

运行结果:

0fbe2f982a03

引用运行结果

参考文档

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实现无限分类方法有多种,其中包括递归和非递归两种方式。下面分别介绍一下这两种方法实现。 1. 递归实现无限分类 递归实现无限分类方法是将分类数据作为一个树形结构来处理。具体实现步骤如下: (1)从数据库中获取所有分类数据,并按照父子关系组织为树形结构。 (2)遍历树形结构,输出每个分类的名称以及子分类的名称。 (3)对于每个子分类,重复步骤(2)。 下面是一个递归实现无限分类的示例代码: ```php function getCategoryTree($parent_id = 0, $level = 0) { $categories = getCategoryByParentId($parent_id); if (count($categories) > 0) { foreach ($categories as $category) { echo str_repeat('-', $level) . $category['name'] . '<br>'; getCategoryTree($category['id'], $level + 1); } } } function getCategoryByParentId($parent_id) { // 从数据库中获取 $parent_id 的所有子分类数据 // ... return $categories; } // 输出所有分类 getCategoryTree(); ``` 2. 非递归实现无限分类递归实现无限分类方法是使用堆栈(或队列)来处理分类数据。具体实现步骤如下: (1)从数据库中获取所有分类数据,并按照父子关系组织为一个数组。 (2)将根分类(即 parent_id 为 0 的分类)入栈。 (3)从堆栈中取出一个分类,并输出该分类的名称。 (4)将该分类的所有子分类依次入栈。 (5)重复步骤(3)和(4),直到堆栈为空。 下面是一个非递归实现无限分类的示例代码: ```php function getCategoryTree() { $categories = getCategoryByParentId(0); $stack = array(); foreach ($categories as $category) { array_push($stack, array('category' => $category, 'level' => 0)); } while (count($stack) > 0) { $current = array_pop($stack); echo str_repeat('-', $current['level']) . $current['category']['name'] . '<br>'; $children = getCategoryByParentId($current['category']['id']); foreach ($children as $child) { array_push($stack, array('category' => $child, 'level' => $current['level'] + 1)); } } } function getCategoryByParentId($parent_id) { // 从数据库中获取 $parent_id 的所有子分类数据 // ... return $categories; } // 输出所有分类 getCategoryTree(); ``` 以上就是php实现无限分类的两种方法。从实现难度和效率上来看,递归方法更简单,但对于数据量较大的情况,可能会导致栈溢出。非递归方法虽然复杂一些,但可以处理更大的数据量。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值