1. 程式人生 > 其它 >前端 js data陣列轉tree資料結構

前端 js data陣列轉tree資料結構

思路

1、首先資料是Excel表格,無pId,但是需要按照目錄層級順序排好(並且是按照到每一層級的最裡層);前端根據目錄層級,進行pId的賦值及取值;

2、為每一條資料新增pId:

  1. 觀察表格資料結構,是否為葉子節點與其他欄位無關,只與上一層級的zIndex大小有關;
  2. 當前項zIndex與前一項的zIndex的大小關係:
    此處zIndex 預設從1開始,是頂層
  • current > before:說明是前一項的子節點,當前項的pId即為前一項的id
  • current === before: 說明他們有相同父節點是兄弟關係,current.pId = before.pId
  • current < before: 說明有多個平級節點,需要往前推,找到最近的兄弟節點,即直接取其pId即可,current.pId = data[n].pId
    此處使用一個for迴圈,根據當前index,往前遞減,找到立即break跳出迴圈,即可
// 根據zIndex:新增 pId 
                    if(item.zIndex === 1){
                        item.pId = null;
                    }else{
                        flag = index;
                        let beforeItem = _data[index - 1];
                        if(beforeItem.zIndex < item.zIndex){
                            item.pId 
= beforeItem.id }else if(beforeItem.zIndex === item.zIndex) { // 相等的情況 item.pId = beforeItem.pId; // 與之前項的pId值同 }else{ // 當前pId < 前一項的 pId for(let n = index; n--; n > flag){
if(_data[n].zIndex === item.zIndex){ console.log("當 前一項時 > 當前zIndex ",beforeItem.name,beforeItem.zIndex,item.name,item.zIndex); console.log(n,_data[n].name,"flag標識--",flag); item.pId = _data[n].pId; // 向上找 找到 同層級 取其pId break; // 遇到立即跳出迴圈 } } } }

難點:根據pId進行樹的資料轉換

參考示例:https://www.cnblogs.com/wjs0509/p/11082850.html

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