JS 將有父子關系的數組轉換成樹形結構數據


    [{
        id: 1,
        name: '1',
    }, {
        id: 2,
        name: '1-1',
        parentId: 1
    }, {
        id: 3,
        name: '1-1-1',
        parentId: 2
    }, {
        id: 4,
        name: '1-2',
        parentId: 1
    }, {
        id: 5,
        name: '1-2-2',
        parentId: 4
    }, {
        id: 6,
        name: '1-1-1-1',
        parentId: 3
    }, {
        id: 7,
        name: '2',
    }]

將以上數據格式  

轉化為一下數據結構類型

[
  {
    "id": 1,
    "name": "1",
    "childrens": [
      {
        "id": 2,
        "name": "1-1",
        "parentId": 1,
        "childrens": [
          {
            "id": 3,
            "name": "1-1-1",
            "parentId": 2,
            "childrens": [
              {
                "id": 6,
                "name": "1-1-1-1",
                "parentId": 3
              }
            ]
          }
        ]
      },
      {
        "id": 4,
        "name": "1-2",
        "parentId": 1,
        "childrens": [
          {
            "id": 5,
            "name": "1-2-2",
            "parentId": 4
          }
        ]
      }
    ]
  },
  {
    "id": 7,
    "name": "2"
  }
]

思路:將有父子關系的數組數據先分為兩類,一類是沒有父節點的數據(取個別名parents),另一類是有父節點的數據(取個別名childrens),然后通過遍歷parents,對每一個父節點在childrens查找對應的子節點,並將其放入父節點的childrens中(這里我的是以childrens表示子節點),然后每個子節點又作為一個父節點來重復之前的動作。(可能這里描述的不太清楚,下面我將對方法進行注釋說明)

/**
 * 該方法用於將有父子關系的數組轉換成樹形結構的數組
 * 接收一個具有父子關系的數組作為參數
 * 返回一個樹形結構的數組
 */
function translateDataToTree(data) {
  //沒有父節點的數據
  let parents = data.filter(value => value.parentId == 'undefined' || value.parentId == null)
 
  //有父節點的數據
  let childrens = data.filter(value => value.parentId !== 'undefined' && value.parentId != null)
 
  //定義轉換方法的具體實現
  let translator = (parents, childrens) => {
    //遍歷父節點數據
    parents.forEach((parent) => {
      //遍歷子節點數據
      childrens.forEach((current, index) => {
        //此時找到父節點對應的一個子節點
        if (current.parentId === parent.id) {
          //對子節點數據進行深復制,這里只支持部分類型的數據深復制,對深復制不了解的童靴可以先去了解下深復制
          let temp = JSON.parse(JSON.stringify(childrens))
          //讓當前子節點從temp中移除,temp作為新的子節點數據,這里是為了讓遞歸時,子節點的遍歷次數更少,如果父子關系的層級越多,越有利
          temp.splice(index, 1)
          //讓當前子節點作為唯一的父節點,去遞歸查找其對應的子節點
          translator([current], temp)
          //把找到子節點放入父節點的childrens屬性中
          typeof parent.childrens !== 'undefined' ? parent.childrens.push(current) : parent.childrens = [current]
        }
      }
      )
    }
    )
  }
 
  //調用轉換方法
  translator(parents, childrens)
 
  //返回最終的結果
  return parents
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM