普通列表(数组)转换成树结构数组

情况一:整个数组转

var list = [
  {
    idSelf: 1,
    label: '苹果',
    idParent: 100
  },
  {
    idSelf: 2,
    label: '茄子',
    idParent: 200
  },
  {
    idSelf: 3,
    label: '香蕉',
    idParent: 100
  },
  {
    idSelf: 4,
    label: '运动类型',
    // idParent: 300
  },
  {
    idSelf: 100,
    label: '水果',
    // idParent: 900
  },
  {
    idSelf: 200,
    label: '蔬菜',
    // idParent: 600
  }
]

实现方式:

// 通过info建立了id=>node的映射
let mapInstance = list.reduce((mapInstance, node) => {
  mapInstance[node.idSelf] = node;
  node.children = [];
  return  mapInstance
}, {})
console.log('mapInstance====', mapInstance)

// 最后arr就是我们转换成功的树结构
const arrNew = list.filter(node => {
  //判断当前node有无父节点
  if (mapInstance[node.idParent]) {
    // 将对应的node放入对应的对象里面去,因为它是浅拷贝,所以会影响原来的数组
    mapInstance[node.idParent].children.push(node)
  }
  //返回没有idParent属性的node(说明是根元素)
  return !node.idParent  // 为 true会返回这个数据,为false则不返回
})
console.log('arrNew====',arrNew)

来看看 mapInstance 和 arrNew 的打印~

情况二:根据某一根节点转

前提:每个对象都有idParent属性

var list = [
  {
    idSelf: 1,
    label: '苹果',
    idParent: 100
  },
  {
    idSelf: 2,
    label: '茄子',
    idParent: 200
  },
  {
    idSelf: 3,
    label: '香蕉',
    idParent: 100
  },
  {
    idSelf: 4,
    label: '运动类型',
    idParent: 300
  },
  {
    idSelf: 100,
    label: '水果',
    idParent: 900
  },
  {
    idSelf: 200,
    label: '蔬菜',
    idParent: 600
  }
]

实现方式:

id——父节点id(首次为根节点); 

arr——需要处理的数组;

var listToTree = (arr, id)=>{
   return arr.filter(item => {
       return item.idParent == id   //过滤找到父节点
   }).map(item_ => {
     return {...item_, children: listToTree(arr, item_.idSelf)}  //根据父节点的id找下层子节点
   })
}
console.log('listToTree',listToTree(list,900))

来看看listToTree的返回值~

补充第三种

let commonList = [
  {id: 1, name: '部门1', pid: 0},
  {id: 2, name: '部门2', pid: 1},
  {id: 3, name: '部门3', pid: 1},
  {id: 4, name: '部门4', pid: 3},
  {id: 5, name: '部门5', pid: 4},
]

var arrToTree = (arr)=>{
  var tempMap = {};   //用于id和对象的一一对应
  var result = [];    //最后的结果
  for(let item of arr){   //遍历数组,for...of返回的是每一项的值
    const id = item.id;    //当前对象的id
    const pid = item.pid;   //当前对象的父节点id

    if(!tempMap[id]){      //如果集合里没有当前对象
      tempMap[id] = {      //则给集合添加一个当前对象对应的id
          children: []      //并加入children属性  {'1': {children: []}}
      }
    }

    tempMap[id] = {   //将当前值与添加的children属性合并成一个完整的对象
      ...item,        //{'1': {id: 1, name: '部门1', pid: 0, children: []}}
      children: tempMap[id]['children']
    }

    const treeItemObj =  tempMap[id];   //从集合对应关系中通过id拿到value,即{id: 1, name: '部门1', pid: 0, children: []}

    if (pid === 0) {    //根节点
      result.push(treeItemObj);   //加入结果数组
    } else {
      if (!tempMap[pid]) {   //当前节点的父节点不存在
        tempMap[pid] = {     //添加一个对应关系,假设pid是6,则 {'6': {children: []}}
          children: [],
        }
      }
      tempMap[pid].children.push(treeItemObj)  //把当前节点加入其父节点中
    }
  }
  return result;   //返回结果
}

console.log('arrToTree===', arrToTree(commonList))
=============================================
[
    {
        "id": 1,
        "name": "部门1",
        "pid": 0,
        "children": [
            {
                "id": 2,
                "name": "部门2",
                "pid": 1,
                "children": []
            },
            {
                "id": 3,
                "name": "部门3",
                "pid": 1,
                "children": [
                    // 结果 ,,,
                ]
            }
        ]
    }
]

猜你喜欢

转载自blog.csdn.net/weixin_44427784/article/details/123577382