将含有父ID的列表转成树
我们知道数据库一般是以一个列表(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的列表转成树的更多相关文章
- 传递一个父id返回所有子id的用法,可用于删除父级以下的所有子级
先在common文件夹建立一个function.php文件,然后写一个递归函数,传递一个父id返回所有子id,如下: function getChildrenId($node,$pid){ $arr= ...
- vue通过id从列表页跳转到对应的详情页
1. 列表页:列表页带id跳转到详情页 详情页:把id传回到后台就可以获取到数据了 2.列表页跳转到详情页并更改详情页的标题 列表页:带id和页面标题的typeid跳转到详情页 详情页:在html绑定 ...
- VUE通过id从列表页跳转到相对的详情页
新闻列表页面: 在这里我用a标签进行跳转,在vue里面可以这样写<router-link></router-link> 1 <router-link :to=" ...
- 无限极分类,传递一个父ID,返回所有子集
方法: static public function getChildren($data,$pid){ $arr=array(); foreach ($data as $v) { if ($v['pi ...
- Oracle由ID生成父ID的函数
/*表结构*/ CREATE TABLE ly_md ( bh BYTE), mc BYTE), pym BYTE), f_bh BYTE), ch NUMBER, ID NUMBER ); INSE ...
- MySQL中进行树状所有子节点的查询 . mysql根据父id 查询所有的子id
在Oracle 中我们知道有一个 Hierarchical Queries 通过CONNECT BY 我们可以方便的查了所有当前节点下的所有子节点.但很遗憾,在MySQL的目前版本中还没有对应的功能. ...
- 递归根据父ID 找所有子类ID
function getinfo($pid){ $str = ''; $row = M('user')->where(array('pid'=>$pid))->select(); i ...
- ajax通过新闻id获取列表
<div class="index_main"> <div class="page_l"> <i ...
- SQL在一张表中根据父ID获取所有的子ID
with a as ( select id,name,parentid from categories where id=53 union all select x.id,x.name,x.paren ...
随机推荐
- SwitchySharp怎样设置 ( proxy switch!的设置与使用方法)
规则列表URL https://autoproxy-G{过}F{滤}Wlist.googlecode.com/svn/trunk/G{过}F{滤}Wlist.txt 注:不同的代{过}{滤}理 相 ...
- 理解ATL中的一些汇编代码(通过Thunk技术来调用类成员函数)
我们知道ATL(活动模板库)是一套很小巧高效的COM开发库,它本身的核心文件其实没几个,COM相关的(主要是atlbase.h, atlcom.h),另外还有一个窗口相关的(atlwin.h), 所以 ...
- android中对线程池的理解与使用
前段时间有幸接到腾讯上海分公司的 Android开发面试,虽然最后一轮被毙了.但还是得总结一下自己在android开发中的一些盲点,最让我尴尬的是面试官问我几个android中线程池的使用与理解..哎 ...
- MPlayer播放器安装
http://www.mplayerhq.hu/MPlayer/releases/MPlayer-1.1.1.tar.xz [tim@L MPlayer-1.1.1]$ mplayer ...
- HDU_1239——再次调用外星智慧
Problem Description A message from humans to extraterrestrial intelligence was sent through the Arec ...
- linux下的java远程调试jpda+tomcat
项目放到linux服务器了,服务器的环境或者数据可能和我们本地不一样,这个时候我们可能需要远程的断点进行调试,来查看请求过程中的各个变量的值.这里我们的应用服务器用的tomcat5.5.17 这个时候 ...
- git命令使用方法
git安装包 http://c35.yunpan.360.cn/my/?sid=#%2F%E5%AE%89%E8%A3%85%E5%8C%85%2FGit%E5%AE%89%E8%A3%85%2F g ...
- checkbox 与JS的应用
JS是一种基于(面向)对象的语言.所有的东西都基本上是对象. 基于对象和面向对象概念上基本上没有什么区别. js没有类,它把类功能称为原型对象.是同一个概念.主要是因为js没有class关键字.类== ...
- android启动优化
############################################## # power on till android lock screen comes up # # get ...
- C编程风格.
C语言编程风格. 关于编程风格,不同书上有不同规范,不同公司都有自己的一套定义.根据自己的编程习惯做个简要说明. 1.变量定义 在定义变量时,前缀使用变量的类型,之后使用表现变量用途的英文单词或单词缩 ...