数组转Tree的思路

1,440 阅读5分钟

数组转Tree

导航菜单需要Tree结构数据,后端返回的是对象数组,对象有id,Pid,这就需要做一些转换工作 代码如下:

//模拟后台返回数据
  let arrData = [
      { id0pidnull },
      { id1pid0 },
      { id2pid0 },
      { id3pid1 },
      { id4pid2 },
      { id5pid3 }
    ]

方法一

<template>
  <div class="Tree"> </div> </template>
<script>
export default {
  name'Tree',
  components: {},
  data () {
    return { } 
  },
  created () {
  //模拟后端返回的菜单数组
    let arrData = [
      { id0Pidnull },
      { id1Pid0 },
      { id2Pid0 },
      { id3Pid1 },
      { id4Pid2 },
      { id5Pid3 }
    ]
    let res = this.arrToTree(arrData) //组装tree 数组
    console.log(res)
  },
  methods: {
    arrToTree (arr) {
      let tempObj = {}
      let result = []
      // 构造一个对象,该对象的key是所有节点的id,value是对应节点
      for (let i = 0, l = arr.length; i < l; i++) {
        tempObj[arr[i].id] = arr[i]
      }
      // 遍历 寻找父节点
      for (let i = 0, l = arr.length; i < l; i++) {
        // pNode 父节点
        let pNode = tempObj[arr[i].Pid]
        // 父节点存在
        if (pNode) {
          if (!pNode.children) {
            pNode.children = []
            pNode.children.push(arr[i])
          } else {
            pNode.children.push(arr[i])
          }
        }
        // 不存在父节点 直接推入result 一级菜单
        else {
          result.push(arr[i])
        }
      }
      return result
    }
  }
}
</script>
<style lang="scss" scoped>
</style>

方法二 (推荐)

<template>
  <div class="Tree">
  </div>
</template>
<script>
export default {
  name'Tree',
  components: {},
  data () {
    return {
    }
  },
  created () {
    let arrData = [
      { id0pidnull },
      { id1pid0 },
      { id2pid0 },
      { id3pid1 },
      { id4pid2 },
      { id5pid3 }
    ]
    let treeMenu = this.getTreeArr({ key'id'pKey'pid'data: arrData, jsonDatafalse })
    console.log(treeMenu)
  },
  methods: {
  /**
   * 将一级的数据结构处理成树状数据结构
   * @param {Object} obj {key, pKey, data}
   *  @param obj.key  字段名称 比如id
   *  @param obj.pKey 父字段名称 比如 pid
   *  @param obj.rootPValue 根节点的父字段的值
   *  @param obj.data 需要处理的数据
   *  @param obj.jsonData 是否深复制数据(默认是true)
   * @return{Array} arr
   */

    getTreeArr(obj) => {
      if (!Array.isArray(obj.data)) {
        console.log('getTreeArr=>请传入数组')
        return []
      }
      obj.jsonData = obj.jsonData === false ? obj.jsonData : true
      const arr = obj.jsonData ? JSON.parse(JSON.stringify(obj.data)) : obj.data
      const arr1 = []
      // 将数据处理成数状结构
      arr.forEach(item => {
        let index = 0
        item.children = []
        arr.forEach(item1 => {
        // 得到树结构关系
          if (item[obj.key] === item1[obj.pKey]) {
            item.children.push(item1)
          }
          // 判断根节点
          if (item1[obj.key] !== item[obj.pKey]) {
            index++
          }
        })
        // 没传入根节点,根据当前数据结构得到根节点
        if (!('rootPValue' in obj) && index === arr.length) {
          arr1.push(item)
        }
      })
      // 传入根节点,根据传入的根节点组成树结构
      if ('rootPValue' in obj) {
        arr.forEach(item => {
          if (item[obj.pKey] === obj.rootPValue) {
            arr1.push(item)
          }
        })
      }
      return arr1
    }

  }
}
</script>
<style lang="scss" scoped>
</style>

本文使用 mdnice 排版