我们知道数据库一般是以一个列表(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. 递归目录的shell脚本

    #! /bin/sh # 在其他目录运行时一定要加上这样的语句 # 尤其是配置在crontab里自动运行 cd `` #定义数据别名 alias statdb="/usr/local/mys ...

  2. JAVA中,数组的操作与排序

    自己写了正向反向的冒泡排序,还用了静态和NEW方法实现. import java.util.Arrays; public class HelloJava { public static void ma ...

  3. Xamarin.Forms-webservices访问

    虽然xamarin.android/ios 均支持右键添加web引用方式引用webservices,但是xamarin.forms不支持此方式,而如果android/ios各做一套采用抽象方式实现则工 ...

  4. android ids.xml资源的使用

    ids.xml文件例子: XML file saved at res/values/ids.xml: 使用方式: 一:

  5. Linux中.a,.la,.o,.so文件的意义和编程实现

    Linux中.a,.la,.o,.so文件的意义和编程实现    Linux下文件的类型是不依赖于其后缀名的,但一般来讲:        .o,是目标文件,相当于windows中的.obj文件     ...

  6. iOS开发手记 - iOS9.3 Xcode7打包ipa文件在其他越狱机器上运行的方法和一些问题

    现在Xcode7可以用一个appleid就可以往手机上部署测试app,不再需要$99,这也是方便.但是要把app发给别人的手机上运行还是不行,除非别人的手机在你身边可以直接通过Xcode安装 关于怎么 ...

  7. 玩转docker

    开篇先论赌 (组词,赌博,....),时刻,每天都在赌! 何为赌?仁者见仁,智者必定又有一番见解,保持沉默,意见保留; ——改变思维模式,Ruiy让赌赢在“思维”!!!; 存在在IT界Ruiy定格,即 ...

  8. ios 限制输入长度

    ----------------UITextField限制输入的长度------------ - (BOOL)textField:(UITextField *)textField shouldChan ...

  9. 微软在线测试题String reorder

    问题描述: Time Limit: 10000msCase Time Limit: 1000msMemory Limit: 256MB DescriptionFor this question, yo ...

  10. ORACLE STUDY NOTES 01

    [JSU]LJDragon's Oracle course notes In the first semester, junior year DML数据操纵语言 DML指:update,delete, ...