1. 程式人生 > 程式設計 >js實現無限層級樹形資料結構(創新演算法)

js實現無限層級樹形資料結構(創新演算法)

由於做專案的需要,把一個線性陣列轉成樹形陣列,在網上查了很多文章,覺得他們寫的太複雜了,於是自己寫了一個,在折騰了一下午終於把它寫出來啦(激動.gif),用兩個filter過濾器就搞定了,程式碼簡潔明瞭,資料結構小白都能看懂。

js程式碼:把扁平資料轉成樹形資料

function setTreeData(source){
  let cloneData = JSON.parse(JSON.stringify(source))   // 對源資料深度克隆
  return cloneData.filter(father=>{           // 迴圈所有項,並新增children屬性
    let branchArr = cloneData.filter(child=> father.id == child.parentId);  // 返回每一項的子級陣列
    branchArr.length>0 ? father.children=branchArr : ''  //給父級新增一個children屬性,並賦值
    return father.parentId==0;   //返回第一層
  });
}

根據網友給我指出的問題,之前的演算法會影響到源資料,之後我對獲取的資料進行了深度克隆,完美解決。

封裝函式:

function treeData(source,id,parentId,children){  
  let cloneData = JSON.parse(JSON.stringify(source))
  return cloneData.filter(father=>{
    let branchArr = cloneData.filter(child => father[id] == child[parentId]);
    branchArr.length>0 ? father[children] = branchArr : ''
    return father[parentId] == 0    // 如果第一層不是parentId=0,請自行修改
  })
}
 
// 呼叫時,欄位名以字串的形式傳參,如treeData(source,'id','parentId','children')

例項1:使用element-ui的元件製作一個樹形多級巢狀伸縮選單欄

實現效果:

js實現無限層級樹形資料結構(創新演算法)

vue元件:

<template>
 <el-tree
  :data="treeData"
  :props="defaultProps"
  accordion
  @node-click="handleNodeClick">
 </el-tree>
</template>
 
<script>
  export default {
    name: "Test",data(){
    return {
     data : [
      {id:1,parentId:0,name:"一級選單A",rank:1},{id:2,name:"一級選單B",{id:3,name:"一級選單C",{id:4,parentId:1,name:"二級選單A-A",rank:2},{id:5,name:"二級選單A-B",{id:6,parentId:2,name:"二級選單B-A",{id:7,parentId:4,name:"三級選單A-A-A",rank:3},{id:8,parentId:7,name:"四級選單A-A-A-A",rank:4},{id:9,parentId:8,name:"五級選單A-A-A-A-A",rank:5},{id:10,parentId:9,name:"六級選單A-A-A-A-A-A",rank:6},{id:11,parentId:10,name:"七級選單A-A-A-A-A-A-A",rank:7},{id:12,parentId:11,name:"八級選單A-A-A-A-A-A-A-A",rank:8},{id:13,parentId:12,name:"九級選單A-A-A-A-A-A-A-A-A",rank:9},{id:14,parentId:13,name:"十級選單A-A-A-A-A-A-A-A-A-A",rank:10},],defaultProps: {
      children: 'children',label: 'name'
     }
    }
   },computed:{
    treeData(){
     let cloneData = JSON.parse(JSON.stringify(this.data))  // 對源資料深度克隆
     return cloneData.filter(father=>{        
      let branchArr = cloneData.filter(child=>father.id == child.parentId)  //返回每一項的子級陣列
      branchArr.length>0 ? father.children = branchArr : ''  //如果存在子級,則給父級新增一個children屬性,並賦值
      return father.parentId==0;   //返回第一層
     });
    }
   },methods:{
    handleNodeClick(data){
     // console.log(data)
     console.log(this.treeData)
    }
   },mounted(){
   }
  }
</script>
 
<style scoped>
 
</style>

Demo

樹形資料轉成扁平資料,請檢視這篇文章:js實現樹形資料轉成扁平資料