1

列表转树一般的需求是将一个包含完整的树形结构(pid=0)的列表转成一个树形。

大题思路各个语言都差不多,将pid设置为0,通过pid 与 id 的关联关系,递归循环,顺藤摸瓜,查询每个节点的下属节点,揪出整个树(文章结尾给出了2个实例)。

有时候我们得到数据不是从pid=0开始的列表,比如从大于第三层级的列表转树,搜索某些关键字的结果列表转树,那应该如何处理呢。

思路

  1. 不能从pid=0开始遍历,那我们只能每个元素进行遍历。
  2. 生成每个元素的子元素列表,递归进行。
  3. 从列表中删除已是其他元素子元素的这些元素。

实现(非完整树结构列表转树)

php

public static function fragmentListToTree(&$list, &$item = null) {

        foreach ($list as $i => &$v) {
            if (is_null($item)) {
                self::fragmentListToTree($list, $v);
            } else {
                if ($v['pid'] == $item['id']) {
                    unset($list[$i]);
                    self::fragmentListToTree($list, $v);
                    $item['chile'][] = $v;
                }
            }
        }
    }

javascript

fragmenBuildTree: function (data) {
    var useIds = []
    var unflatten = function (array, parent) {
        if (parent === undefined) {
            array.forEach(function (child) { unflatten(array, child) });
        } else {
            var children = array.filter(function (child) {
                return child ? child.parentId == parent.id : '';
            });

            if (children && children.length) {
                parent['children'] = children
                parent['leaf'] = false;
                
                children.forEach(function (child) {
                    useIds.push(child.id)
                    unflatten(array, child)
                });
            } else {
                parent['leaf'] = true;
                parent['children'] = []
            }
        }
        return array;
    }

    var tmp = unflatten(data)
    var tree = tmp.filter(function (child) {
        for(var i in useIds){
            if(useIds[i] === child.id){
                return false;
            }
        }
        return true;
    });
    return tree;
}

列表转树(完整树结构)

php

public static function listToTree($list, $pid = 0) {
        $arr = [];
        foreach ($list as $v) {
            if ($v['pid'] == $pid) {
                $v['chile'] = self::listToTree($list, $v['id']);
                $arr[] = $v;
            }
        }

        return $arr;
    }

javascript

buildTree: function (data) {
      
        var unflatten = function (array, parent, tree) {
          
            tree = typeof tree !== 'undefined' ? tree : [];
            parent = typeof parent !== 'undefined' ? parent : { id: 0 };
             
            var children = array.filter(function (child) {
                return child ? child.parentId == parent.id : '';
            });
    
            if (children && children.length) {
                if (parent.id == 0) {
                    tree = children;
                } else {
                    parent['children'] = children
                }
                parent['leaf'] = false;
                children.forEach(function (child) { unflatten(array, child) });
            } else {
                parent['leaf'] = true;
                parent['children'] = []
            }

            return tree;
        }
        return unflatten(data);
    }

liyiyang
76 声望2 粉丝