数组遍历区分父子级重排遍历多维数组

背景:在开发实战中,后台传给前台的数据是一个数组,数组根据id和pId一一对应具有父子级关系,

如:第一个对象 a.id='1' ;a.pid='0';

第二个对象 b.id='5'; b.pid='1';

第三个对象 c.id='7'; c.pid='5';

这样,a.pid='0'; a就是为第一级父元素,b.pid=a.id 则对象a就是对象b的父级, 以此类推,对象b就是对象c的父级。

实战:先看后台返回数据

rows: [,…]
0: {id: "1", name: "系统管理", pId: "0", istype: "0", code: "system", page: "/", icon: "", zindex: "999",…}
1: {id: "2", name: "用户管理", pId: "1", istype: "0", code: "usermanage", page: "/user/userList", icon: "",…}
2: {id: "3", name: "角色管理", pId: "1", istype: "0", code: "rolemanage", page: "/auth/roleManage", icon: "",…}
3: {id: "4", name: "权限管理", pId: "1", istype: "0", code: "permmanage", page: "/auth/permList", icon: null,…}
4: {id: "5", name: "CDN管理", pId: "0", istype: "0", code: "nginx", page: "/", icon: null, zindex: "300",…}
5: {id: "13", name: "节点列表", pId: "5", istype: "0", code: "nginx", page: "/nginx/nodeList", icon: null,…}
6: {id: "14", name: "站点管理", pId: "5", istype: "0", code: "nginx", page: "/nginx/nginxList", icon: null,…}
7: {id: "15", name: "访问记录", pId: "5", istype: "0", code: "nginx", page: "/visitor/visitorList",…}
8: {id: "17", name: "nginx统计", pId: "5", istype: "0", code: "nginx", page: "/statis/toNginxStatistic",…}
9: {id: "18", name: "产品管理", pId: "5", istype: "0", code: "nginx", page: "/product/productList",…}
10: {id: "19", name: "安全管理", pId: "5", istype: "0", code: "nginx", page: "/safe/safeManagement",…}
11: {id: "20", name: "站点检测", pId: "5", istype: "0", code: "nginx", page: "/website/websiteDetection",…}
12: {id: "21", name: "DNS管理", pId: "5", istype: "0", code: "nginx", page: "/dns/dnsManagement", icon: null,…}
13: {id: "22", name: "节点更新", pId: "1", istype: "0", code: "nginx", page: "/sys/sysUpdate", icon: null,…}
14: {id: "23", name: "版本更新", pId: "1", istype: "0", code: "nginx", page: "/version/versionManage",…}
15: {id: "24", name: "操作日志", pId: "1", istype: "0", code: "system", page: "/sys/toOperateLog", icon: null,…}
16: {id: "25", name: "转移记录", pId: "5", istype: "0", code: "nginx", page: "/transfer/transferList",…}
17: {id: "27", name: "1101", pId: "0", istype: "0", code: "2113", page: "211", icon: null, zindex: "1131",…}
18: {id: "29", name: "日志封禁记录", pId: "5", istype: "0", code: "nginx", page: "/logBan/logBanList",…}
19: {id: "43", name: "22", pId: "27", istype: "0", code: "22", page: "22", icon: null, zindex: "22",…}
20: {id: "44", name: "23", pId: "43", istype: "0", code: "23", page: "23", icon: null, zindex: "23",…}
21: {id: "45", name: "24", pId: "44", istype: "0", code: "24", page: "24", icon: null, zindex: "24",…}
22: {id: "47", name: "25", pId: "45", istype: "0", code: "", page: "25", icon: null, zindex: null,…}
23: {id: "48", name: "11", pId: "27", istype: "0", code: "", page: "11", icon: null, zindex: null,…}

再看前台需要展示的样式

如上图所示:父级包含子级,层层包含,折叠展示;

吐槽:由于后台并没有最数据处理,需要前台做处理排序然后按要求展示; 

思路:第一步

数组深度复制,变成两个相同的数组,然后遍历去重处理。

//遍历数组 
circleArray(arr) {
       // 1.根据id个pid建立两个去重数组
      let pIds = new Set()   
      let ids = new Set()
        // 2.遍历数组
      for (let item of arr) {
        item.children = []
        pIds.add(item.pId)
        ids.add(item.id)
      }
         //3. 得到两个去重数组
      pIds = Array.from(pIds)
      ids = Array.from(ids)
         //4.数组深拷贝得到新数组arr2 调用下面递归函数
      let arr2 = this.deepCopy(arr)
        //5.再次遍历数组并调用函数
      for (let ele of arr) {
        this.circleSleep(ele, arr, arr2, pIds)
      }
    },
// 递归函数 用于深拷贝
deepCopy(obj) {
      let result = Array.isArray(obj) ? [] : {}
      for (let key in obj) {
        if (obj.hasOwnProperty(key)) {
          if (typeof obj[key] === 'object') {
            result[key] = this.deepCopy(obj[key]) // 递归复制
          } else {
            result[key] = obj[key]
          }
        }
      }
      return result
    },

思路:第二步

根据得到的新数组进行双重遍历,重排和删除多余元素

// 根据新得到的数组重排筛选数组
circleSleep(ele, arr, arr2, pIds) {
        // 1.遍历arr2
      for (let item of arr2) {
        // 2.如果arr2的父级pid 等于 arr的id
        if (item.pId === ele.id) {
        // 3.就把arr2的对象push到对应的arr.children[]中
          ele.children.push(item)
        // 4.根据对象的pid相同取出对应下标
          let index3 = arr.findIndex(cur => {
            return cur.pId === item.pId
          })
        // 5.再来判断pIds数组中是否包含这个元素
          if (pIds.includes(item.id)) {
        // 6.如果有则函数自调用
            this.circleSleep(item, arr, arr2, pIds)
          }
        // 7.根据对应下边删除arr中的对象
          arr.splice(index3, 1)
        }
      }
    },

这样就可以了,你可以得到一个数组对象里面包含多级数组对象的数组,哈哈有点绕,希望大家可以看懂。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章