爱程序网

将含有父ID的列表转成树

来源: 阅读:

我们知道数据库一般是以一个列表(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         empty($item[$childKey]) && $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) {          }        }      }    }  }}

成功把列表转成了树

相关文章列表:
关于爱程序网 - 联系我们 - 广告服务 - 友情链接 - 网站地图 - 版权声明 - 人才招聘 - 帮助