[英]Javascript Recursive function to build Tree
嗨,我使用JavaScript
和jQuery
作為客戶端腳本。 我對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.