• 将含有父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) {
              }
            }
          }
        }
      }
    }

    成功把列表转成了树

  • 相关阅读:
    实战MEF(4):搜索范围
    实战MEF(3):只导出类的成员
    Mac 配置 php-fpm 时出现'/private/etc/php-fpm.conf': No such file or directory (2)
    如何实现在H5里调起高德地图APP?
    PHPExcel 基本用法详解
    最简单的css实现页面宽度自适应
    去掉IntelliJ IDEA 中 mybatis 对应的 xml 文件警告
    SQLyog恢复数据库报错解决方法【Error Code: 2006
    解决svn log显示no author,no date的方法之一
    Centos 7(Linux)环境下安装PHP(编译添加)相应动态扩展模块so(以openssl.so为例)
  • 原文地址:https://www.cnblogs.com/365star/p/5217738.html
Copyright © 2020-2023  润新知