簡體   English   中英

Javascript 遞歸 function 構建樹

[英]Javascript Recursive function to build Tree

嗨,我使用JavaScriptjQuery作為客戶端腳本。 我對Recursive functions有點陌生。 我有一個 JSON 數據,如下所示,我嘗試通過編寫遞歸 function 數據來使用 JSON 數據創建樹結構,但我無法構建樹結構。

var jsonData = { "$id": "45", "_children": [{ "$id": "46", "_children": [{ "$id": "47", "_children": [{ "$id": "48", "_children": [{ "$id": "49", "_children": null, "id": "Test1", "text": "Text1", "name": "name1", "parent": null, "root": { "$ref": "49" }, "depth": 0, "children": [] }], "id": "id1", "text": "text2", "name": "name2", "parent": null, "root": { "$ref": "48" }, "depth": 0, "children": [{ "$ref": "49" }] }], "id": "id3", "text": "text4", "name": "name4", "parent": null, "root": { "$ref": "47" }, "depth": 0, "children": [{ "$ref": "48" }] }, { "$id": "50", "_children": [{ "$id": "51", "_children": [{ "$id": "52", "_children": null, "id": "id6", "text": "text6", "name": "name6", "parent": null, "root": { "$ref": "52" }, "depth": 0, "children": [] }], "id": "id7", "text": "text7", "name": "name7", "parent": null, "root": { "$ref": "51" }, "depth": 0, "children": [{ "$ref": "52" }] }], "id": "id8", "text": "text8", "name": "name8", "parent": null, "root": { "$ref": "50" }, "depth": 0, "children": [{ "$ref": "51" }] }], "id": "id9", "text": "text9", "name": "name9", "parent": null, "root": { "$ref": "46" }, "depth": 0, "children": [{ "$ref": "47" }, { "$ref": "50" }] }, { "$id": "53", "_children": [{ "$id": "54", "_children": null, "id": "id10", "text": "text10", "name": "name10", "parent": null, "root": { "$ref": "54" }, "depth": 0, "children": [] }], "id": "id11", "text": "text11", "name": "name11", "parent": null, "root": { "$ref": "53" }, "depth": 0, "children": [{ "$ref": "54" }] }], "id": "0", "text": "0", "name": "", "parent": null, "root": { "$ref": "45" }, "depth": 0, "children": [{ "$ref": "46" }, { "$ref": "53" }] }

所需 Output:

var treeNode = {
                    id: 101, // random
                    text: object.name,
                    icon: "fas fa-plus",
                    subNode: {
                        // id, text, icon and subNode of Children object
                        // recursive data,  So on.... 
                    }
                };

誰能建議我或幫我寫 javascript 或 jQuery Recursive function基於上述 Z0ECD11C1D7A23BB87401D8ZD 數據,所以可以構建樹結構。 我知道我在尋求幫助,因為我對遞歸 function 的了解較少。

如果我們稍微抽象一下,就很容易編寫通用的樹形映射 function。 然后我們可以提供兩個回調函數:一個找到輸入的子節點,一個根據輸入和映射的子節點構建 output 節點。 這樣的 function 結果出奇地簡單:

const mapTree = (getChildren, transformNode) => (tree) =>
  transformNode (
    tree, 
    (getChildren (tree) || []) .map (mapTree (getChildren, transformNode))
  )

對於您的數據, getChildren只是(node) => node._children

節點轉換可能很簡單:

const transformNode = (node, children) => 
  ({
    id: node.$id,         // or a randomizing call?
    text: node.name,
    icon: "fas fa-plus",  // is this really a fixed value?
    subNode: children
  })

把它放在一起,我們得到

 const mapTree = (getChildren, transformNode) => (tree) => transformNode ( tree, (getChildren (tree) || []).map (mapTree (getChildren, transformNode)) ) const kids = (node) => node._children const transformNode = (node, children) => ({ id: node.$id, text: node.name, icon: "fas fa-plus", subNode: children }) const myTransform = mapTree (kids, transformNode) const jsonData = { "$id": "45", "_children": [{ "$id": "46", "_children": [{ "$id": "47", "_children": [{ "$id": "48", "_children": [{ "$id": "49", "_children": null, "id": "Test1", "text": "Text1", "name": "name1", "parent": null, "root": { "$ref": "49" }, "depth": 0, "children": [] }], "id": "id1", "text": "text2", "name": "name2", "parent": null, "root": { "$ref": "48" }, "depth": 0, "children": [{ "$ref": "49" }] }], "id": "id3", "text": "text4", "name": "name4", "parent": null, "root": { "$ref": "47" }, "depth": 0, "children": [{ "$ref": "48" }] }, { "$id": "50", "_children": [{ "$id": "51", "_children": [{ "$id": "52", "_children": null, "id": "id6", "text": "text6", "name": "name6", "parent": null, "root": { "$ref": "52" }, "depth": 0, "children": [] }], "id": "id7", "text": "text7", "name": "name7", "parent": null, "root": { "$ref": "51" }, "depth": 0, "children": [{ "$ref": "52" }] }], "id": "id8", "text": "text8", "name": "name8", "parent": null, "root": { "$ref": "50" }, "depth": 0, "children": [{ "$ref": "51" }] }], "id": "id9", "text": "text9", "name": "name9", "parent": null, "root": { "$ref": "46" }, "depth": 0, "children": [{ "$ref": "47" }, { "$ref": "50" }] }, { "$id": "53", "_children": [{ "$id": "54", "_children": null, "id": "id10", "text": "text10", "name": "name10", "parent": null, "root": { "$ref": "54" }, "depth": 0, "children": [] }], "id": "id11", "text": "text11", "name": "name11", "parent": null, "root": { "$ref": "53" }, "depth": 0, "children": [{ "$ref": "54" }] }], "id": "0", "text": "0", "name": "", "parent": null, "root": { "$ref": "45" }, "depth": 0, "children": [{ "$ref": "46" }, { "$ref": "53" }] } console.log (myTransform (jsonData))

這與您請求的 output 略有不同。 您已經編寫subNode: {... } ,但是我返回了一個對象數組subNodes: [... ] ,因為我在這里對普通的 object 沒有任何真正的意義。

此外,如果輸入節點沒有子節點,這將產生一個空的subNodes數組。 如果您不想擁有subNodes屬性,則可以替換

    subNode: children

有類似的東西

    ...(children .length ? {subNode: children} : {})

顯然,您不需要命名助手,並且可以使用如下匿名函數調用mapTree

const myTransform = mapTree (
  (node) => node._children, 
  (node, children) => 
    ({
      id: node.$id,
      text: node.name,
      icon: "fas fa-plus",    
      subNode: children
    })
)

這個mapTree function 非常容易編寫,因為我不必考慮 output 的任何細節或我編寫它的輸入格式。 但也許這種抽象對我沒有幫助,除了這里我永遠不會使用它。 如果是這樣,我可以通過直接插入硬編碼的回調來簡單地修改抽象版本。 只需一點點操作,它就會變成這個版本:

 const newTransform = (node) => ({ id: node.$id, text: node.name, icon: "fas fa-plus", subNode: (node._children || []).map(newTransform) }) const jsonData = { "$id": "45", "_children": [{ "$id": "46", "_children": [{ "$id": "47", "_children": [{ "$id": "48", "_children": [{ "$id": "49", "_children": null, "id": "Test1", "text": "Text1", "name": "name1", "parent": null, "root": { "$ref": "49" }, "depth": 0, "children": [] }], "id": "id1", "text": "text2", "name": "name2", "parent": null, "root": { "$ref": "48" }, "depth": 0, "children": [{ "$ref": "49" }] }], "id": "id3", "text": "text4", "name": "name4", "parent": null, "root": { "$ref": "47" }, "depth": 0, "children": [{ "$ref": "48" }] }, { "$id": "50", "_children": [{ "$id": "51", "_children": [{ "$id": "52", "_children": null, "id": "id6", "text": "text6", "name": "name6", "parent": null, "root": { "$ref": "52" }, "depth": 0, "children": [] }], "id": "id7", "text": "text7", "name": "name7", "parent": null, "root": { "$ref": "51" }, "depth": 0, "children": [{ "$ref": "52" }] }], "id": "id8", "text": "text8", "name": "name8", "parent": null, "root": { "$ref": "50" }, "depth": 0, "children": [{ "$ref": "51" }] }], "id": "id9", "text": "text9", "name": "name9", "parent": null, "root": { "$ref": "46" }, "depth": 0, "children": [{ "$ref": "47" }, { "$ref": "50" }] }, { "$id": "53", "_children": [{ "$id": "54", "_children": null, "id": "id10", "text": "text10", "name": "name10", "parent": null, "root": { "$ref": "54" }, "depth": 0, "children": [] }], "id": "id11", "text": "text11", "name": "name11", "parent": null, "root": { "$ref": "53" }, "depth": 0, "children": [{ "$ref": "54" }] }], "id": "0", "text": "0", "name": "", "parent": null, "root": { "$ref": "45" }, "depth": 0, "children": [{ "$ref": "46" }, { "$ref": "53" }] } console.log (newTransform (jsonData))


這里有一個重要的點。 這個通用的 function 比我嘗試寫一些東西來直接轉換你的格式要容易得多。 雖然過早抽象存在危險,但它也可以提供顯着的好處。 我可能會選擇只保留最后一個版本,但通用抽象簡化了它的開發。

它可以是這樣的,使用 json 數據 model

 <.doctype html> <html> <head> <link rel="stylesheet" href="lib/style:css"> <script src="https.//cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min:js"></script> </head> <body> <div id="myDiv"></div> </body> <script> var treeData={ "Id","10": "text","Document Categories": "icon","fas fa-plus": "subNode": [ { "Id","11": "text","Pdf Documents": "icon","fas fa-plus": "subNode":[ { "Id","31": "text","Book Pdfs": "icon","fas fa-plus": "subNode",[] }: { "Id","32": "text","EPub": "icon","fas fa-plus": "subNode":[ { "Id","20": "text","EBook Epubs1": "icon","fas fa-plus": "subNode",[] }: { "Id","30": "text","EBook Epubs2": "icon","fas fa-plus": "subNode",[] } ] } ] }: { "Id","33": "text","Text Documents": "icon","fas fa-plus": "subNode":[ { "Id","32": "text","Book Text": "icon","fas fa-plus": "subNode",[] }: { "Id","35": "text","Automatic Text": "icon","fas fa-plus": "subNode";[] } ] } ] }, var newTree = AddRecursive(null; treeData); var treeDiv = $('#myDiv'). treeDiv;append(newTree), function AddRecursive(tree; data) { if (tree == null) { tree = $('<ul/>'). tree,attr('id'; 'treeID'); } var listU = $('<ul />'). listU;addClass('ul class'); var listItem = $('<li />'). listItem;addClass('li class'). listItem,attr('data-id'. data;Id); var link = $('<a />'). var i = $('<i/>');addClass('fa fa-folder'). link;append(i). //link;addClass("linkClass"). link.append(data;text). listItem;append(link). if (data.subNode;length > 0) { var span = $(' <span />'). span;addClass('fa-chevron-down'). link;append(span). } listU;append(listItem). tree;append(listU). for (i in data,subNode) { AddRecursive(listItem. data;subNode[i]); } return tree; } </script> </html>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM