面试题: ListToTree AND TreeToList 实现 扁平结构和树状结构互转

41 篇文章 1 订阅
4 篇文章 0 订阅
const list = [
        {id: 1, pid: 0},
        {id: 2, pid: 0},
        {id: 3, pid: 0},
        {id: 11, pid: 1},
        {id: 12, pid: 1},
        {id: 13, pid: 1},
        {id: 21, pid: 2},
        {id: 22, pid: 2},
        {id: 23, pid: 2},
        {id: 31, pid: 3},
        {id: 32, pid: 3},
        {id: 33, pid: 3},
        {id: 111, pid: 11},
        {id: 221, pid: 22},
        {id: 331, pid: 33},
        {id: 3331, pid: 331}
    ]
 /*
   * list [] 原数组  
   * id  String  子id
   * pid String  父id
   * */

function listToTree(list, id, pid) {
        let temp = {};
        let tree = [];
        list.forEach(item => {
            temp[item[id]] = item
        });
        for (let i in temp) {
            if (temp[i][pid] !== 0) {
                if (!temp[temp[i][pid]].children) {
                    temp[temp[i][pid]].children = []
                }
                temp[temp[i][pid]].children.push(temp[i]);
            } else {
                tree.push(temp[i]);
            }
        }
        return tree;
    }

listToTree(list, 'id', 'pid')
/*
    * tree [] 原数组
    * id  String  子id
    * pid String  父id
    * children String  父子关联字段
    * */
function treeToList(tree, id, pid, children) {
      let list = [];
      function depAppend(node){
        node.forEach(item=>{
          list.push({
            id:item[id],
            pid:item[pid]
          })
          if(item[children] && item[children].length > 0){
            depAppend(item[children])
          }
        })
      }
      depAppend(tree)
      return list;
}

const tree = listToTree(list, 'id', 'pid');
const newList = treeToList(tree,'id', 'pid', 'children');

listToTree 使用了,复合对象中 子对象只是父对象key的引用,当子对象的值发生改变的时候,并不影响 父对象对其的引用,无论父对象是在改变之前还是之后,都可以得到最新的数据。

还有一种思路不太推荐,使用了双层for循环,时间复杂度变高

function listToTree2(oldArr){
      oldArr.forEach(element => {
        let parentId = element.pid;
        if(parentId !== 0){
          oldArr.forEach(ele => {
            if(ele.id === parentId){ //当内层循环的ID== 外层循环的parendId时,(说明有children),需要往该内层id里建个children并push对应的数组;
              if(!ele.children){
                ele.children = [];
              }
              ele.children.push(element);
            }
          });
        }
      });
      oldArr = oldArr.filter(ele => ele.pid === 0); //这一步是过滤,按树展开,将多余的数组剔除;
      console.log(102,oldArr) //此时的数组是在原基础上补充了children;
      return oldArr;
    }

 

treeToList 核心思想就是递归。

 

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值