我们知道数据库一般是以一个列表(id,pid)的形式保存树的。如何提取这棵树呢?最简单的方法就是根据pid循环查表。但是毫无疑问,这会产生巨大的数据库查询开销。

那么一般建议的方法是一次性将全部相关数据全查出来,但是这就涉及到一个问题,如何快速的构建一棵树。

我曾经一直以为,这是一个复杂的操作,至少需要一个递归,时间复杂度不会是O(n)。

前段时间,一个工作上的需求,需要解决这个问题。我仔细想了想,发现完全可以通过单层循环解决这个问题,实现如下:

 function list2Tree($listItem, $idx = 'id', $pIdx = 'pid', $childKey= 'list'){
$map = array();
$pMap = array(); foreach($listItem as $item){
$id = $item[$idx];
$pid = $item[$pIdx];
$map[$id] = &$item;
unset($item);
} foreach($map as $id => &$item){
$pid = $item[$pIdx];
empty($item[$childKey]) && $item[$childKey] = array(); if(! isset($map[$pid])){
$pMap[$id] = &$item;
}
else{
$pItem= &$map[$pid];
$pItem[$childKey][] = &$item;
} unset($item, $pItem);
} return array_shift($pMap);
}

测试一下:

 // 路径方便识别父子关系
$json = <<<JSON
[
{
"id": 2,
"pid": 1,
"path": "/se"
},
{
"id": 3,
"pid": 2,
"path": "/se/4901"
},
{
"id": 4,
"pid": 5,
"path": "/se/4901/mask/query"
},
{
"id": 5,
"pid": 3,
"path": "/se/4901/mask"
},
{
"id": 6,
"pid": 2,
"path": "/se/4902"
},
{
"id": 7,
"pid": 6,
"path": "/se/4902/mask"
}
]
JSON; $list = json_decode($json, true); var_dump(list2Tree($list));

结果:

array(4) {
["id"]=>
int(2)
["pid"]=>
int(1)
["path"]=>
string(3) "/se"
["list"]=>
array(2) {
[0]=>
array(4) {
["id"]=>
int(3)
["pid"]=>
int(2)
["path"]=>
string(8) "/se/4901"
["list"]=>
array(1) {
[0]=>
array(4) {
["id"]=>
int(5)
["pid"]=>
int(3)
["path"]=>
string(13) "/se/4901/mask"
["list"]=>
array(0) {
}
}
}
}
[1]=>
array(4) {
["id"]=>
int(6)
["pid"]=>
int(2)
["path"]=>
string(8) "/se/4902"
["list"]=>
array(1) {
[0]=>
array(4) {
["id"]=>
int(7)
["pid"]=>
int(6)
["path"]=>
string(13) "/se/4902/mask"
["list"]=>
array(0) {
}
}
}
}
}
}

成功把列表转成了树

将含有父ID的列表转成树的更多相关文章

  1. 传递一个父id返回所有子id的用法,可用于删除父级以下的所有子级

    先在common文件夹建立一个function.php文件,然后写一个递归函数,传递一个父id返回所有子id,如下: function getChildrenId($node,$pid){ $arr= ...

  2. vue通过id从列表页跳转到对应的详情页

    1. 列表页:列表页带id跳转到详情页 详情页:把id传回到后台就可以获取到数据了 2.列表页跳转到详情页并更改详情页的标题 列表页:带id和页面标题的typeid跳转到详情页 详情页:在html绑定 ...

  3. VUE通过id从列表页跳转到相对的详情页

    新闻列表页面: 在这里我用a标签进行跳转,在vue里面可以这样写<router-link></router-link> 1 <router-link :to=" ...

  4. 无限极分类,传递一个父ID,返回所有子集

    方法: static public function getChildren($data,$pid){ $arr=array(); foreach ($data as $v) { if ($v['pi ...

  5. Oracle由ID生成父ID的函数

    /*表结构*/ CREATE TABLE ly_md ( bh BYTE), mc BYTE), pym BYTE), f_bh BYTE), ch NUMBER, ID NUMBER ); INSE ...

  6. MySQL中进行树状所有子节点的查询 . mysql根据父id 查询所有的子id

    在Oracle 中我们知道有一个 Hierarchical Queries 通过CONNECT BY 我们可以方便的查了所有当前节点下的所有子节点.但很遗憾,在MySQL的目前版本中还没有对应的功能. ...

  7. 递归根据父ID 找所有子类ID

    function getinfo($pid){ $str = ''; $row = M('user')->where(array('pid'=>$pid))->select(); i ...

  8. ajax通过新闻id获取列表

    <div class="index_main">        <div class="page_l">           <i ...

  9. SQL在一张表中根据父ID获取所有的子ID

    with a as ( select id,name,parentid from categories where id=53 union all select x.id,x.name,x.paren ...

随机推荐

  1. 移动端app测试

    对于手机项目(应用软件),主要是进行系统测试. 而针对手机应用软件的系统测试,我们通常从如下几个角度开展测试工作: 功能模块测试: 交叉事件测试: 性能测试: 安全测试: 容量测试: 兼容性测试: 接 ...

  2. MATLAB 常用形态学操作函数

    常用形态学操作函数(转自:http://blog.sina.com.cn/s/blog_4c52e9e20100e5if.html) 1.dilate函数 该函数能够实现二值图像的膨胀操作,有以下形式 ...

  3. PHP 之isset() 与 unset()

    isset()用来判断某个变量是否已经被声明,他返回一个boolean类型的值,如果声明则返回true否则返回false.如果变量被声明后,给他赋值为NULL,他也返回false. 如: <?p ...

  4. ELK( ElasticSearch+ Logstash+ Kibana)分布式日志系统部署文档

    开始在公司实施的小应用,慢慢完善之~~~~~~~~文档制作 了好作运维同事之间的前期普及.. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 软件下载地址: https://www.e ...

  5. 【HDOJ】4544 湫湫系列故事——消灭兔子

    贪心,普通贪心两层循环TLE了,然后用优先级队列维护内层. #include <iostream> #include <cstdio> #include <cstring ...

  6. centos6.5+Django+mysql+nginx+uwsgi

    centos6.5+Django+mysql+nginx+uwsgi 1.nginx的安装.这里采用nginx-1.6.0, 建立一个shell脚本然后执行. #!/bin/bash nginx_ve ...

  7. http协议使用实例

    #include <stdio.h>#include <windows.h>#include <wininet.h> #define MAXSIZE 1024#pr ...

  8. bzoj3995[SDOI2015]道路修建

    http://www.lydsy.com/JudgeOnline/problem.php?id=3995 线段树维护连通性. 我们发现,对于一个区间[L,R],我们只需要知道(1,L),(2,L),( ...

  9. 关于apriori算法的一个简单的例子

    apriori算法是关联规则挖掘中很基础也很经典的一个算法,我认为很多教程出现大堆的公式不是很适合一个初学者理解.因此,本文列举一个简单的例子来演示下apriori算法的整个步骤. 下面这个表格是代表 ...

  10. 使用MapReduce将HDFS数据导入到HBase(二)

    package com.bank.service; import org.apache.hadoop.conf.Configuration;import org.apache.hadoop.conf. ...