• 省市区多级联动数据组合


    话不多说,直接说重点。最近用到了省市区数据联动。数据格式是这样的:

      $array = [
                0 => [
                    'id' => 1,
                    'pid' => 0,
                    'name' => 't1',
                ],
                1 => [
                    'id' => 2,
                    'pid' => 0,
                    'name' => 't2',
                ],
                2 => [
                    'id' => 3,
                    'pid' => 0,
                    'name' => 't3',
                ],
                3 => [
                    'id' => 4,
                    'pid' => 1,
                    'name' => 't1-t4',
                ],
                4 => [
                    'id' => 5,
                    'pid' => 2,
                    'name' => 't2-t5',
                ],
                5 => [
                    'id' => 6,
                    'pid' => 4,
                    'name' => 't1-t4-t6',
                ],
            ];

    返回格式要求是这样的:

     Array
    (
        [0] => Array
            (
                [id] => 1
                [pid] => 0
                [name] => t1
                [child] => Array
                    (
                        [0] => Array
                            (
                                [id] => 4
                                [pid] => 1
                                [name] => t1-t4
                                [child] => Array
                                    (
                                        [0] => Array
                                            (
                                                [id] => 6
                                                [pid] => 4
                                                [name] => t1-t4-t6
                                            )
    
                                    )
    
                            )
    
                    )
    
            )
    
        [1] => Array
            (
                [id] => 2
                [pid] => 0
                [name] => t2
                [child] => Array
                    (
                        [0] => Array
                            (
                                [id] => 5
                                [pid] => 2
                                [name] => t2-t5
                            )
    
                    )
    
            )
    
        [2] => Array
            (
                [id] => 3
                [pid] => 0
                [name] => t3
            )
    
    )

    在知道数组层级且层级比较少的情况下,最简单粗暴的方式当然是多层遍历组装数组。但是这样显然有点 low。来说三种比较洋气的方式。

    递归

    首先想到的当然是递归。递归的本质也是遍历循环,效率应该相差不多,但是代码量明显减少,看起来清爽了很多。

        function getOptionsTree($array, $pid = 0)
        {
            $optionsTree = [];
            foreach ($array as $key => $item){
                //假设从根节点开始,pid 为0,将根节点元素放入数组
                if ($item['pid'] == $pid){
                    $optionsTree[$item['id']] = $item;
                    //销毁已查询的,减轻下次递归查询数量
                    unset($array[$key]);
                    //递归开始,查询根节点的子类,并将其元素放入根节点下的 child 中
                    $optionsTree[$item['id']]['child'] = $this->getOptionsTree($array, $item['id']);
                }
            }
    
            return $optionsTree;
        }

    栈递归

    该方法暂时只能处理2层数据,后期待优化。但是重点不是这个方法,而是利用栈来解决问题的思路。该方法利用了栈 先进后出,即后进先出 的特点,通过入栈、出栈来达到数据组合的目的。

       function getTreeOptions($array, $pid = 0)
        {
            $tree = [];
            if (!empty($array)) {
                //先取出顶级的来压入数组$stack中,并将在$list中的删除掉
                $stack = [];
                foreach ($array as $key => $value) {
                    if ($value['pid'] == $pid) {
                        array_push($stack,$value);
                        unset($array[$key]);
                    }
                }
    
                while (count($stack)) {
                    //先从栈中取出第一项
                    $info = array_pop($stack);
                    if ($info['pid'] == 0){
                        $tree[$info['id']] = $info;
                    }else{
                        $tree[$info['pid']]['child'][$info['id']] = $info;
                    }
    
                    //查询剩余的$list中pid与其id相等的,也就是查找其子节点
                    foreach ($array as $key => $child) {
                        if ($child['pid'] == $info['id']) {
                            //如果有子节点则入栈,while循环中会继续查找子节点的下级
                            array_push($stack,  $child);
                            unset($array[$key]);
                        }
                    }
                }
            }
            return $tree;
        }

    引用

    首推方法。引用赋值,就是说将赋值左边的直接指向内存中存储这个值的这块区域,如 $b = &$a,$a 和 $b 在内存中指向的值的区域是相同的,因此当这块区域的值被改变,两个变量都会被改变。

    明白这一点,这个方法也就可以看明白了。

        function getTreeOptions($list, $pid = 0)
        {
            $tree = [];
            if (!empty($list)) {
                //先修改为以id为下标的列表
                $newList = [];
                foreach ($list as $k => $v) {
                    $newList[$v['id']] = $v;
                }
                //然后开始组装成特殊格式
                foreach ($newList as $value) {
                    if ($pid == $value['pid']) {//先取出顶级
                        $tree[] = &$newList[$value['id']];
                    } elseif (isset($newList[$value['pid']])) {//再判定非顶级的pid是否存在,如果存在,则再pid所在的数组下面加入一个字段items,来将本身存进去
                        $newList[$value['pid']]['child'][] = &$newList[$value['id']];
                    }
                }
            }
            return $tree;
        }

    好文章要分享:

    https://www.cnblogs.com/vishun/p/6716483.html

  • 相关阅读:
    angular2 如何使用animate实现动画效果
    angular2+ 组件中用@import进来的css不起作用
    ReentrantLock & AQS
    常用JDK命令
    分布式缓存
    持续交付
    持续部署
    持续集成
    领域驱动设计简介
    spring boot 整合JPA bean注入失败
  • 原文地址:https://www.cnblogs.com/suojian/p/13964955.html
Copyright © 2020-2023  润新知