时间:2021-07-01 10:21:17 帮助过:7人阅读
我们知道数据库一般是以一个列表(id,pid)的形式保存树的。如何提取这棵树呢?最简单的方法就是根据pid循环查表。但是毫无疑问,这会产生巨大的数据库查询开销。
那么一般建议的方法是一次性将全部相关数据全查出来,但是这就涉及到一个问题,如何快速的构建一棵树。
我曾经一直以为,这是一个复杂的操作,至少需要一个递归,时间复杂度不会是O(n)。
前段时间,一个工作上的需求,需要解决这个问题。我仔细想了想,发现完全可以通过单层循环解决这个问题,实现如下:
1 function list2Tree($listItem, $idx = 'id', $pIdx = 'pid', $childKey= 'list'){ 2 $map = array(); 3 $pMap = array(); 4 5 foreach($listItem as $item){ 6 $id = $item[$idx]; 7 $pid = $item[$pIdx]; 8 $map[$id] = &$item; 9 unset($item); 10 } 11 12 foreach($map as $id => &$item){ 13 $pid = $item[$pIdx]; 14 $item[$childKey] = array(); 15 16 if(! isset($map[$pid])){ 17 $pMap[$id] = &$item; 18 } 19 else{ 20 $pItem= &$map[$pid]; 21 $pItem[$childKey][] = &$item; 22 } 23 24 unset($item, $pItem); 25 } 26 27 return array_shift($pMap); 28 }
测试一下:
1 // 路径方便识别父子关系 2 $json = <<<JSON 3 [ 4 { 5 "id": 2, 6 "pid": 1, 7 "path": "/se" 8 }, 9 { 10 "id": 3, 11 "pid": 2, 12 "path": "/se/4901" 13 }, 14 { 15 "id": 4, 16 "pid": 5, 17 "path": "/se/4901/mask/query" 18 }, 19 { 20 "id": 5, 21 "pid": 3, 22 "path": "/se/4901/mask" 23 }, 24 { 25 "id": 6, 26 "pid": 2, 27 "path": "/se/4902" 28 }, 29 { 30 "id": 7, 31 "pid": 6, 32 "path": "/se/4902/mask" 33 } 34 ] 35 JSON; 36 37 $list = json_decode($json, true); 38 39 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) { } } } } } }
成功把列表转成了树
http://www.bkjia.com/PHPjc/1102845.htmlwww.bkjia.comtruehttp://www.bkjia.com/PHPjc/1102845.htmlTechArticle将含有父ID的列表转成树,id列表成树 我们知道数据库一般是以一个列表(id,pid)的形式保存树的。如何提取这棵树呢?最简单的方法就是根据...