PHP无限极分类-一次循环模式(不使用递归)

在平时工作中, 经常需要将普通列表数据, 处理成树, 列表数据结构大致如下:


+----+--------------+-----+
| id | name         | pid |
+----+--------------+-----+
|  1 | 媒体(白名单) |   0 |
|  2 | 党媒公共平台 |   0 |
|  3 | 政府机构     |   0 |
|  4 | 其他         |   0 |
|  5 | 中央媒体     |   1 |
|  6 | 地方媒体     |   1 |
|  7 | 门户媒体     |   4 |
|  8 | 综合媒体     |   4 |
|  9 | 专业媒体     |   4 |
| 11 | 河北省       |   6 |
| 12 | 山东省       |   6 |
| 13 | 辽宁省       |   6 |
| 34 | 北京         |   6 |
| 45 | 视频         |   9 |
| 46 | 教育         |   9 |
| 79 | 法律         |   9 |
| 80 | 其他         |   9 |
| 81 | 文学         |   9 |
+----+--------------+-----+

常规实现方式是使用递归模式, 但是在笔者工作中, 需要处理很大的数据量, 使用递归, 会严重影响性能,  而用<b>一次循环方式也可以很好的处理</b>在处理大数据量时, 性能会提示非常多

完整代码如下

<?php

header('Content-Type:application/json;charset=UTF-8');
$src = '[{"id":"1","name":"媒体(白名单)","pid":"0"},{"id":"2","name":"党媒公共平台","pid":"0"},{"id":"3","name":"政府机构","pid":"0"},{"id":"4","name":"其他","pid":"0"},{"id":"5","name":"中央媒体","pid":"1"},{"id":"6","name":"地方媒体","pid":"1"},{"id":"7","name":"门户媒体","pid":"4"},{"id":"8","name":"综合媒体","pid":"4"},{"id":"9","name":"专业媒体","pid":"4"},{"id":"11","name":"河北省","pid":"6"},{"id":"12","name":"山东省","pid":"6"},{"id":"13","name":"辽宁省","pid":"6"},{"id":"34","name":"北京","pid":"6"},{"id":"45","name":"视频","pid":"9"},{"id":"46","name":"教育","pid":"9"},{"id":"79","name":"法律","pid":"9"},{"id":"80","name":"其他","pid":"9"},{"id":"81","name":"文学","pid":"9"}]';

$result = json_decode($src, true);
echo json_encode(listToTree($result), JSON_UNESCAPED_UNICODE);

/**
 * 核心函数, 将列表数据转化树形结构
 * 使用前提必须是先有父后有子, 即儿子的id必须小于父亲id
 * 列表数据必须安装id从小到大排序
 * @param $lists 原始列表数据
 * @param string $childKey 字段名
 * @return array 返回树形数据
 */
function listToTree($lists, $childKey = 'children'){
    $map = [];
    $res = [];
    foreach($lists as $id => &$item){
        // 获取出每一条数据的父id
        $pid = &$item['pid'];
        // 将每一个item的引用保存到$map中
        $map[$item['id']] = &$item;
        // 如果在map中没有设置过他的pid, 说明是根节点, pid为0,
        if(!isset($map[$pid])){
            // 将pid为0的item的引用保存到$res中
            $res[$id] = &$item;
        }else{
            // 如果在map中没有设置过他的pid, 则将该item加入到他父亲的叶子节点中
            $pItem = &$map[$pid];
            $pItem[$childKey][] = &$item;
        }
    }
    return $res;
}

最终处理结果如下:

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值