关于深复制以及平铺数据转为树形结构

13 篇文章 0 订阅
1 篇文章 0 订阅
关于深复制以及平铺数据转为树形结构
  • 本次代码背景为后端返回的平铺的组织架构数据需要转换为树形结构,最后面有封装后的代码

  • 需要根据cAxis来判断层级,然后根据sortId与pid进行push

  • `
//深复制函数
 function deepClone(obj) {
                    function isObject(o) { return (typeof o === 'object' || typeof o === 'function') && o !== null }
                    if (!isObject(obj)) { throw new Error('非对象') }
                    let isArray = Array.isArray(obj)
                    let newObj = isArray ? [...obj] : { ...obj };
                    Reflect.ownKeys(newObj).forEach(key => { newObj[key] = isObject(obj[key]) ? deepClone(obj[key]) : obj[key] }); return newObj
                };

                let newList = deepClone(arrAll);
                newList = newList.map((item) => {
                    item.Id = item.sortId;
                    item.Name = item.sortName;
                    //可以按照item.Count去判断是否有必要展示下级
                    item.IsEnd = item.isEnd;
                    item.type = type;
                    item.typeName = Name;
                    if (!item.IsEnd) {
                        item.child = [];
                    }
                    return item
                })
                let lastList = [];
                newList.forEach(item => {
                    const str = item.cAxis.split(/\$/);
                    const index = str.length - 3;
                    if (lastList[index] && Array.isArray(lastList[index])) {
                        lastList[index].push(item);
                    } else {
                        lastList[index] = [item]
                    }
                })
                for (let i = (lastList.length - 1); i > 0; i--) {
                    lastList[i].forEach(item => {
                        const str = item.cAxis.match(/\d+/g);
                        if (lastList[i - 1]) {
                            lastList[i - 1].forEach(items => {
                                if (items.sortId === item.pid) {
                                    if (items.child && Array.isArray(items.child)) {
                                        items.child.push(deepClone(item))
                                    } else {
                                        items.child = [deepClone(item)];
                                    }
                                }
                            })
                        }
                    })
                }

`


  • 二次封装,主要用于算法的解耦,方便复用
  • 数据源如下
  • `

const newList = [{
    "sortName": "集团单位",
    "pid": "0",
    "isEndUsed": 0,
    "domainEvents": [],
    "ownerId": "1807323",
    "enterId": "1805435",
    "recordId": 0,
    "icfo": "0",
    "establishTime": "0001-01-01T00:00:00",
    "sortId": "2106221744230000109",
    "orgCode": "03",
    "isMaster": 1,
    "createdTime": "2021-06-22T17:44:23",
    "cFullName": "集团单位",
    "inheritanceId": "636346361736274263",
    "sortRank": 0,
    "sortRankNum": 2,
    "isUseMarket": 0,
    "isEnd": 0,
    "isUsed": 1,
    "createdDate": "0001-01-01T00:00:00",
    "iceo": "0",
    "isMust": 0,
    "cAxis": "$2106221744230000109$",
    "sortOrder": 1,
    "modifiedDate": "0001-01-01T00:00:00",
    "isDel": 0,
    "isUseUnit": 1,
    "lastUpdateTime": "2022-05-24T13:50:10"
  },
  {
    "sortName": "单位一级",
    "pid": "2106221744230000109",
    "isEndUsed": 0,
    "domainEvents": [],
    "ownerId": "1950569",
    "enterId": "1805435",
    "recordId": 0,
    "icfo": "0",
    "establishTime": "2021-07-19T00:00:00",
    "sortId": "202107200236411553",
    "orgCode": "",
    "isMaster": 1,
    "createdTime": "2021-07-20T10:36:41",
    "cFullName": "集团单位/单位一级",
    "inheritanceId": "636346361736274263",
    "sortRank": 1,
    "sortRankNum": 2,
    "isUseMarket": 0,
    "isEnd": 0,
    "isUsed": 1,
    "createdDate": "0001-01-01T00:00:00",
    "iceo": "0",
    "isMust": 0,
    "cAxis": "$2106221744230000109$202107200236411553$",
    "sortOrder": 1,
    "modifiedDate": "0001-01-01T00:00:00",
    "isDel": 0,
    "isUseUnit": 1,
    "lastUpdateTime": "2022-08-19T16:00:13"
  },
  {
    "sortName": "单位二级",
    "pid": "202107200236411553",
    "isEndUsed": 0,
    "domainEvents": [],
    "ownerId": "1801976",
    "enterId": "1805435",
    "recordId": 0,
    "icfo": "0",
    "establishTime": "2021-07-20T00:00:00",
    "sortId": "202107200820254831",
    "orgCode": "",
    "isMaster": 1,
    "createdTime": "2021-07-20T16:20:25",
    "cFullName": "集团单位/单位一级/单位二级",
    "inheritanceId": "636346361736274263",
    "sortRank": 2,
    "sortRankNum": 0,
    "isUseMarket": 0,
    "isEnd": 1,
    "isUsed": 1,
    "createdDate": "0001-01-01T00:00:00",
    "iceo": "0",
    "isMust": 0,
    "cAxis": "$2106221744230000109$202107200236411553$202107200820254831$",
    "sortOrder": 1,
    "modifiedDate": "0001-01-01T00:00:00",
    "isDel": 0,
    "isUseUnit": 1,
    "lastUpdateTime": "2021-07-20T16:20:25"
  }
];


  • 代码二次封装如下
const tilingToTree = (list, option) => {
      const deepClone = (obj) => {
        function isObject(o) {
          return (typeof o === "object" || typeof o === "function") && o !== null;
        }
        if (!isObject(obj)) {
          throw new Error("非对象");
        }
        let isArray = Array.isArray(obj);
        let newObj = isArray
          ? [...obj]
          : {
              ...obj,
            };
        Reflect.ownKeys(newObj).forEach((key) => {
          newObj[key] = isObject(obj[key]) ? deepClone(obj[key]) : obj[key];
        });
        return newObj;
      };
      // 判断是否为数组,且数组是否有元素
      if (!Array.isArray(list) || !list.length) return;
      // 为防止数组不可修改
      const newList = deepClone(list);
      const newOption = option || {
        keyName: "",
        parentKeyName: "sortId",
        childKeyName: "pid",
        contactKeyName: "child",
      };
      // 先创建一个用来根据层级存储数据的数组
      const sequenceList = [];
      // 遍历数据源,用来根据层级决定在sequenceList数组中存储位置
      newList.forEach((item) => {
        let hierarchy;
        //如有直接显示的层级keyName,其中item[newOption.keyName]直接就是层级
        if (newOption.keyName && item[newOption.keyName]) {
          // 减一是层级一般从一级开始,但是索引从0开始
          hierarchy = item[newOption.keyName] - 1;
        } else {
          const str = item.cAxis.split(/\$/);
          hierarchy = str.length - 3;
        }
        // 如果数组中对应层级数字的索引存在且是数组,选择直接push
        if (sequenceList[hierarchy] && Array.isArray(sequenceList[hierarchy])) {
          sequenceList[hierarchy].push(item);
        } else {
          // 否则将item用数组包裹放到改索引位置
          sequenceList[hierarchy] = [item];
        }
      });
      // 此处使用遍历递减,即从层级数字最大的(官小的开始)
      for (let i = sequenceList.length - 1; i > 0; i--) {
        // 从数组中的最后一个数组开始遍历
        sequenceList[i].forEach((item) => {
          // 判断它的上级是否存在
          if (sequenceList[i - 1]) {
            // 遍历他的上级
            sequenceList[i - 1].forEach((items) => {
              // 如果他上级的sortId等于下级的pid
              if (items[newOption.parentKeyName] === item[newOption.childKeyName]) {
                //如果上级的child属性存在,且是数组
                if (
                  items[newOption.contactKeyName] &&
                  Array.isArray(items[newOption.contactKeyName])
                ) {
                  items[newOption.contactKeyName].push(deepClone(item));
                } else {
                  items[newOption.contactKeyName] = [deepClone(item)];
                }
              }
            });
          }
        });
      }
      // 返回最上级(老板级)
      return sequenceList[0];
    };


    console.log(tilingToTree(newList), "tilingToTree");
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值