tree 的递归算法

tree的数据结构:
tree = [
 {
    check: false,
    children: [
        check: false,
        children: [
          {  
             {
                check: false,
                children: [
                    {
                           check: false,
                           children: [],
                           code: "SD2016082600160",
                           disabled: false,
                            isLeaf: true,
                            label: "金泰荔湾小区",
                            name: "金泰荔湾小区",
                            open: false,
                            orgLeaf: false,
                            parentCode: "O04464422616",
                            parentName: "测试超长字段的组织",
                            projectCodeList: []   
                     }
                ],
                code: "O04464422616"
                disabled: false,
                isLeaf: false,
                label: "测试超长字段的组织",
                name: "测试超长字段的组织",
                open: false,
                orgLeaf: true,
                parentCode: "080311bbbe8642899d325742b2073805",
                projectCodeList: ["SD2016082600160"]
           },
           {
               check: false,
                children: [],
                code: "SD2016082600170",
                disabled: false,
                isLeaf: true,
                label: "高德公寓",
                name: "高德公寓",
                open: false,
                orgLeaf: false,
                parentCode: "080311bbbe8642899d325742b2073805",
                parentName: "集中管控标准版",
                projectCodeList: []
            }
          }, 
          {
                check: false,
                children: [],
                code: "p201809211",
                disabled: false,
                isLeaf: true,
                label: "集中管控测试项目",
                name: "集中管控测试项目",
                open: false,
                orgLeaf: false,
                parentCode: "fb3087611f248d93d67330b4938fff8e",
                parentName: "集中管控多项目集团",
                projectCodeList: []
           } 
        ],
        code: "080311bbbe8642899d325742b2073805",
        disabled: false,
        isLeaf: false,
        label: "集中管控标准版",
        name: "集中管控标准版",
        open: false,
        orgLeaf: false,
        parentCode: "fb3087611f248d93d67330b4938fff8e",
        projectCodeList: ["SD2016082600170"]
    ],
    code: "fb3087611f248d93d67330b4938fff8e",
    disabled: false,
    isLeaf: false,
    label: "集中管控多项目集团",
    name: "集中管控多项目集团",
    open: false,
    orgLeaf: false,
    projectCodeList: ["p201811081", "p201809211",             SD2016082600190", "SD2016082600164", "SD2016082600196",…]   
  }   
]                                                          
View Code

 

1.根据code ,寻找tree里面的选中对象

export function getActiveNode(tree,code){ tree: [{}] // 树型结构
  let node = {};
  finds(tree,code);
  function finds(tree,code) {
    for(let i=0;i<tree.length;i++){
      if(tree[i].code == code){
        node = tree[i]
      } else {
        if(tree[i].children && tree[i].children.length>0){
          finds(tree[i].children,code)
        }
      }
    }
  }
  return node;
}

 

2. 通过code筛选组织树节点,输出 [{}]

export function filterNode (tree, code) {
  if (!code) {return}
  let resultArr = []
  for (let i = 0; i < tree.length; i++) {
    let item = tree[i]
    if (item.code == code) {
      resultArr.push(item)
      return resultArr
    } else if (item.children && item.children.length) {
      resultArr = filterNode(item.children, code)
    }
  }
  return resultArr
}

 2.1  通过code找到对应节点,输出{}

let findNode = function (arr, code) {
        for (let i = 0, len = arr.length; i < len; i++) {
          let syncNode = arr[i]
          if(syncNode.path == code){
            return syncNode;
          }
          if (syncNode.children && syncNode.children.length) {
            const foundNode = findNode(syncNode.children, code)
            if (foundNode) {
              return foundNode
            }
          }
        }
        return null
 }
 findNode (arr, code)

 

3.有父子关系的数组转换成树形结构的数组

/**
* 该方法用于将有父子关系的数组转换成树形结构的数组
* 接收一个具有父子关系的数组作为参数
* 返回一个树形结构的数组 
*/
export function translateDataToTree (data) {
  let parents = data.filter((item,index) => {return index === data.length-1})
  //有父节点的数据
  let childrens = data.filter(value => value.parentCode)
  //定义转换方法的具体实现
  let translator = (parents, childrens) => {
    parents.forEach((parent) => {
      childrens.forEach((current, index) => {
        if (current.parentCode === parent.code) {
          //对子节点数据进行深复制,这里只支持部分类型的数据深复制,对深复制不了解的童靴可以先去了解下深复制
          let temp = JSON.parse(JSON.stringify(childrens))
          //让当前子节点从temp中移除,temp作为新的子节点数据,这里是为了让递归时,子节点的遍历次数更少,如果父子关系的层级越多,越有利
          temp.splice(index, 1)
          //让当前子节点作为唯一的父节点,去递归查找其对应的子节点
          translator([current], temp)
          //把找到子节点放入父节点的childrens属性中
          typeof parent.children !== 'undefined' ? parent.children.push(current) : parent.children = [current]
          
        }
      })
    })
  }
  //调用转换方法
  translator(parents, childrens)
  //返回最终的结果
  console.log(parents)
  return parents
}

 4. 递归获取第一个节点下面的第一个叶子节点 


// 查找一个树第一个节点的第一个叶子节点,深度遍历
getFirstNode (tree) {
        var temp = {}
        var forFn = function (arr) {
          if (arr && arr.length > 0) {
            temp = arr[0]
            if (arr[0].children) {
              forFn(arr[0].children)
            }
          }
        }
        forFn(tree)
        return temp
      }

// 遍历,获取第一个子元素下面的叶子节点,如果没有叶子节点,则去children里面找,依次类推,知道找到位置
    getFirstNode (data) {
            let node = {}
            let forFn = (data) => {
                data.forEach(el => {
                    if (el.isLeaf) {
                        node = el
                    } else if (el.children && el.children.length) {
                        if (el.children.findIndex(v => v.isLeaf) > -1) {
                            node = el.children.find(v => v.isLeaf)
                        } else {
                            forFn(el.children)
                        }
                    }
                })
            }
            forFn(data)
            return node
        },

5. 递归获取第一个节点下面的所有的第一个节点

  // 查找一个树多个第一个节点,深度遍历
    getFirstNode (tree) {
      var temp = []
      var forFn = function (arr) {
        if (arr && arr.length > 0) {
          temp.push(arr[0])
          if (arr[0].children) {
            forFn(arr[0].children)
          }
        }
      }
      forFn(tree)
      return temp
    }

 6. 递归删除树结构所有的叶子节点

    // 删除树结构所有叶子节点
    treeDataHandle(tree) {
          let newArr = [];
          for (let i = 0; i < tree.length; i++){
            let item = tree[i];
            if(item.isLeaf === true) {
                tree.splice(i--, 1);  // 这里不可用delete,会有语法报错,i--,是删掉第i个后,索引需要减1
            } else {
                if (item.children && item.children.length) {
                    item.children = this.treeDataHandle(item.children);
                }
                newArr.push(item);
            }
          }
          // console.log('最终处理的结果', newArr)
          return newArr
        }

 7. 递归给树结构每一项添加 value, label,children 属性,chils 数组为空,不添加children

export function addPropertys (tree) {
  let forFn = function (arr) {
    arr.forEach(item => { // 此刻arr.forEach改变了预原数组的值arr,所以直接返回出去了arr,原因是 Object.assign(item, {}),这里是直接改变了item的值,item没有重新指向,如果使用 item = Obejct.assign({}, item, {}),item重新指向后,arr值就不会改变了
if (item.childs && item.childs.length) {
        forFn(item.childs)
      }
      item.childs && item.childs.length? Object.assign(item,{value: item.areaId, label: item.name, children: item.childs}):Object.assign(item,{value: item.areaId, label: item.name})
      
    })
    return arr
  }
  let result = forFn(tree)
  return result
}

备注:forEach 会不会改变原数组 查看 原理

posted @ 2020-07-13 17:22  front-gl  阅读(1729)  评论(0编辑  收藏  举报