成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

關于樹形插件展示中數(shù)據(jù)結構轉換的算法

王晗 / 1690人閱讀

摘要:舉例說明如下二維數(shù)據(jù)結構總部二級門店三級門店二級門店樹狀數(shù)據(jù)結構總部二級門店三級門店二級門店但在某些插件中,或在某些特殊場景中,我們有兩種數(shù)據(jù)結構之間相互轉換的需求,需要自己寫一個輔助函數(shù)來完成。

問題背景

在一些目錄結構、機構層級等展示的場景中,我們經(jīng)常會用到一些成熟的樹形插件來進行輕松展示,比如ztree等。大多數(shù)插件會支持對兩種數(shù)據(jù)源格式的解析,一種是通用的二維數(shù)據(jù)結構,一種是樹狀數(shù)據(jù)結構。對于這兩種數(shù)據(jù)結構的稱呼在各插件中可能不盡相同,這里依照二維結構和樹狀結構來稱呼。舉例說明如下:

// 二維數(shù)據(jù)結構
[{
  "id": "001",
  "name": "總部",
  "parentId": "0"
}, {
  "id": "002",
  "name": "二級門店1",
  "parentId": "001"
}, {
  "id": "003",
  "name": "三級門店",
  "parentId": "002"
}, {
  "id": "004",
  "name": "二級門店2",
  "parentId": "001"
}]

// 樹狀數(shù)據(jù)結構
[{
    "id": "001",
    "name": "總部",
    "parentId": "0",
    "children": [{
      "id": "002",
      "name": "二級門店1",
      "parentId": "001",
      "children": [{
        "id": "003",
        "name": "三級門店",
        "parentId": "002",
        "children": []
      }]
    }, {
      "id": "004",
      "name": "二級門店2",
      "parentId": "001",
      "children": []
    }]
}]

但在某些插件中,或在某些特殊場景中,我們有兩種數(shù)據(jù)結構之間相互轉換的需求,需要自己寫一個輔助函數(shù)來完成。這里就提供兩個這樣的工具函數(shù)來完成數(shù)據(jù)結構的轉換。

Note: 要說明的是,工具函數(shù)沒有經(jīng)過大數(shù)據(jù)量轉換測試,所以對有實時性、大量源數(shù)據(jù)轉換需求的同學而言,請自行測試分析,可采取前置或異步等方案處理。由于自身技術水平的局限性,算法本身會有性能優(yōu)化的空間,若有更優(yōu)處理算法,還望交流分享,謝謝!

解決方案

我們來分開介紹兩種數(shù)據(jù)結構之間的轉換算法,每個小結中我會先貼出整個函數(shù)的代碼清單,以便大家復制粘貼,然后會簡要說明其中大概的邏輯思路。

二維數(shù)據(jù)結構 => 樹狀數(shù)據(jù)結構
/**
 * 將通用的二維數(shù)據(jù)結構轉換為樹狀數(shù)據(jù)結構
 * @param  {String} rootParentIdValue 表示根節(jié)點的父類id值
 * @param  {String} parentIdName      表示父類id的節(jié)點名稱
 * @param  {String} nodeIdName        表示二維結構中,每個對象主鍵的名稱
 * @param  {Array} listData           為二維結構的數(shù)據(jù)
 * @return {Array}                    轉換后的tree結構數(shù)據(jù)
 */
function listToTree(rootParentIdValue, parentIdName, nodeIdName, listData) {
  if (listData instanceof Array && listData.length > 0 && listData[0][parentIdName]) {
    var rootList = [],
        nodeList = []
      
    listData.forEach(function(node, index) {
      if (node[parentIdName] == rootParentIdValue) {
        rootList.push(node);
      } else {
        nodeList.push(node);
      }
    });

    if (nodeList.length > 0 && rootList.length > 0) {
      childrenNodeAdd(rootList, nodeList);
      return rootList;
    } else if (rootList.length > 0) {
      throw new Error("沒有對應的子節(jié)點集合");
    } else {
      throw new Error("沒有對應的父類節(jié)點集合");
    }

    function childrenNodeAdd(rootNodeList, childrenList) {
      if (childrenList.length > 0) { 
        rootNodeList.forEach(function(rootNode) {
          rootNode["children"] = [];
          var childrenNodeList = childrenList.slice(0); 
          childrenList.forEach(function(childrenNode, childrenIndex) {
            if (parentIdName in childrenNode && rootNode[nodeIdName] == childrenNode[parentIdName]) {
              rootNode["children"].push(childrenNode);
              childrenNodeList.splice(childrenIndex, 1);
            }
          });
          childrenNodeAdd(rootNode["children"], childrenNodeList);
        });
      }
    }
    
  } else {
    throw new Error("格式不正確,無法轉換");
  }
}

此函數(shù)可通過listToTree("0", "parentId", "id", sourceData)調(diào)用測試,sourceData為文章開頭給出的二維數(shù)據(jù)結構舉例。

下面簡要介紹一下其中邏輯,第10行是簡要驗證一下入?yún)?shù)據(jù)的合法性,然后聲明了rootList和nodeList兩個變量。其中rootList為頂級根節(jié)點,nodeList為其他子節(jié)點集合,第14行到20行的循環(huán)便是為兩個變量賦值,之后根據(jù)兩個變量的值進一步判斷數(shù)據(jù)的合法性。在驗證之后調(diào)用childrenNodeAdd這個內(nèi)部函數(shù),此函數(shù)之后將會被遞歸調(diào)用,為每一個節(jié)點添加指定名稱為“children”的子節(jié)點數(shù)組。兩個入?yún)⒎謩e是rootNodeList和childrenList,代表父節(jié)點集合,和其之后的所有子節(jié)點集合。在23行第一次調(diào)用時,傳入的便是頂級根節(jié)點和其之后的所有子孫節(jié)點。下面看這段帶有詳細注解的代碼片段:

function childrenNodeAdd(rootNodeList, childrenList) {
      if (childrenList.length > 0) { //  如果沒有子節(jié)點了就結束遞歸
        //遍歷父節(jié)點集合,在子節(jié)點中查找其自身的子節(jié)點,并添加到對應的子節(jié)點數(shù)組中
        rootNodeList.forEach(function(rootNode) {
          rootNode["children"] = [];
          var childrenNodeList = childrenList.slice(0); //復制一個子節(jié)點數(shù)據(jù),用于存放剩余的子節(jié)點
          //遍歷所有子節(jié)點
          childrenList.forEach(function(childrenNode, childrenIndex) {
            if (parentIdName in childrenNode && rootNode[nodeIdName] == childrenNode[parentIdName]) { //根節(jié)點的id 等于子節(jié)點的父類id
              rootNode["children"].push(childrenNode); //添加對應節(jié)點歸為子節(jié)點
              childrenNodeList.splice(childrenIndex, 1);//在剩余子節(jié)點中剔除已經(jīng)分配過的子節(jié)點
            }
          });
          childrenNodeAdd(rootNode["children"], childrenNodeList); //剩余子節(jié)點繼續(xù)遞歸執(zhí)行,每次遞歸一次就表示節(jié)點增加一級。
        });
      }
    }
樹狀數(shù)據(jù)結構 => 二維數(shù)據(jù)結構
/**
 * 將樹狀數(shù)據(jù)結構轉換為二維數(shù)據(jù)結構
 * @param  {String} childrenName 樹狀結構中子節(jié)點名稱
 * @param  {Array} treeData     樹狀結構數(shù)據(jù)
 * @return {Array}              轉換后的通用二維結構數(shù)據(jù)
 */
function treeToList(childrenName, treeData) {
  var listData = [];
  transferTreeData(treeData);
  function transferTreeData (sourceData) {
     sourceData.forEach( function(node, nodeIndex) {
     if(node[childrenName].length > 0)
          transferTreeData(node[childrenName]);
      delete node[childrenName];
      listData.push(node);
     });
  }
  return listData;
}

此函數(shù)可通過treeToList("children", sourceData)調(diào)用測試,sourceData為文章開頭給出的樹狀數(shù)據(jù)結構舉例。這里的邏輯比較簡單就不再贅述了。

文章版權歸作者所有,未經(jīng)允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉載請注明本文地址:http://m.hztianpu.com/yun/90515.html

相關文章

  • 用JavaScript自己寫MVVM前端框架-VM實現(xiàn)篇

    摘要:關于前端框架大家都有了解,或多或少的使用過,比如,,等等。那么你是否也想自己手寫一個的前端框架呢,我們從入手,手把手教你寫基于的前端框架,在整個編寫的過程中,希望大家學習更多,理解更多。本節(jié)我們以打包工具結合轉換插件實現(xiàn)數(shù)據(jù)的抽象。 關于MVVM前端框架大家都有了解,或多或少的使用過,比如Angular,React,VUE等等。那么你是否也想自己手寫一個MVVM的前端框架呢,我們從Vi...

    VincentFF 評論0 收藏0
  • 前端數(shù)據(jù)結構算法(1)-- dfs

    摘要:前端在開發(fā)過程中接觸到的算法最多的莫過于排序和深度優(yōu)先遍歷。關于算法的遍歷過程,我簡略的畫了一個示例圖實例最近在實際業(yè)務場景中,跟后端約定頁面中所有組件的消息根據(jù)頁面上的組件聚合到一個對象中,后端返回的是類似如下的一個樹形數(shù)據(jù)結構。 showImg(https://segmentfault.com/img/remote/1460000010632752); dfs 前端在開發(fā)過程中接觸...

    hizengzeng 評論0 收藏0
  • [譯]148個資源讓你成為CSS專家

    摘要:層疊樣式表二修訂版這是對作出的官方說明。速查表兩份表來自一份關于基礎特性,一份關于布局。核心第一篇一份來自的基礎參考指南簡寫速查表簡寫形式參考書使用層疊樣式表基礎指南,包含使用的好處介紹個方法快速寫成高質(zhì)量的寫出高效的一些提示。 迄今為止,我已經(jīng)收集了100多個精通CSS的資源,它們能讓你更好地掌握CSS技巧,使你的布局設計脫穎而出。 CSS3 資源 20個學習CSS3的有用資源 C...

    impig33 評論0 收藏0
  • react diff算法

    摘要:算法的本質(zhì)是對傳統(tǒng)遍歷算法的優(yōu)化策略用三大策略將復雜度轉化為復雜度策略一中節(jié)點跨層級的移動操作特別少,可以忽略不計。當節(jié)點處于同一層級時,提供三種節(jié)點操作刪除插入移動。在舊的節(jié)點中的,它的,不滿足的條件,因此不做移動操作。 一、react diff算法 diff算法的作用 計算出Virtual DOM中真正變化的部分,并只針對該部分進行原生DOM操作,而非重新渲染整個頁面。 傳統(tǒng)di...

    imccl 評論0 收藏0
  • SICP Python 描述 3.2 函數(shù)和所生成過程

    摘要:函數(shù)和所生成的過程來源譯者飛龍協(xié)議函數(shù)是計算過程的局部演化模式。在這一章中,我們會檢測一些用于簡單函數(shù)所生成過程的通用模型。也就是說,遞歸函數(shù)的執(zhí)行過程可能需要再次調(diào)用這個函數(shù)。 3.2 函數(shù)和所生成的過程 來源:3.2 Functions and the Processes They Generate 譯者:飛龍 協(xié)議:CC BY-NC-SA 4.0 函數(shù)是計算過程的局部演化...

    lolomaco 評論0 收藏0

發(fā)表評論

0條評論

王晗

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<