猿问

用于构建树的Javascript递归函数

我正在使用JavaScript和jQuery作为客户端脚本。我对Recursive functions. 我有一个 JSON 数据,如下所示,我尝试通过编写递归函数使用下面的 JSON 数据制作树结构,但我无法构建树结构。


所需输出:


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.... 

                    }

                };

任何人都可以建议我或帮助我Recursive function根据上述 JSON 数据编写 javascript 或 jQuery ,以便我可以构建树结构。我知道我在寻求帮助,因为我对递归函数的了解较少。


神不在的星期二
浏览 171回答 2
2回答

大话西游666

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

阿波罗的战车

如果我们稍微抽象一下,就可以很容易地编写一个通用的树映射函数。然后我们可以提供两个回调函数:一个查找输入的子节点,一个根据输入和映射的子节点构建输出节点。事实证明,这样的函数出奇的简单:const mapTree = (getChildren, transformNode) => (tree) =>&nbsp; transformNode (&nbsp; &nbsp; tree,&nbsp;&nbsp; &nbsp; (getChildren (tree) || []) .map (mapTree (getChildren, transformNode))&nbsp; )对于您的数据,getChildren简直就是(node) => node._children节点转换可能很简单:const transformNode = (node, children) =>&nbsp;&nbsp; ({&nbsp; &nbsp; id: node.$id,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// or a randomizing call?&nbsp; &nbsp; text: node.name,&nbsp; &nbsp; icon: "fas fa-plus",&nbsp; // is this really a fixed value?&nbsp; &nbsp; subNode: children&nbsp; })把这些放在一起,我们得到const mapTree = (getChildren, transformNode) => (tree) =>&nbsp; transformNode (&nbsp; &nbsp; tree,&nbsp;&nbsp; &nbsp; (getChildren (tree) || []) .map (mapTree (getChildren, transformNode))&nbsp; )const kids = (node) => node._childrenconst transformNode = (node, children) =>&nbsp;&nbsp; ({&nbsp; &nbsp; id: node.$id,&nbsp; &nbsp; text: node.name,&nbsp; &nbsp; icon: "fas fa-plus",&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; subNode: children&nbsp; })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))这与您请求的输出略有不同。你写了subNode: { ... },但我返回了一个对象数组,subNodes: [ ... ],因为我在这里没有任何真正意义上的普通对象。此外,subNodes如果输入节点没有子节点,这将产生一个空数组。如果您不想拥有该subNodes财产,则可以更换&nbsp; &nbsp; subNode: children像&nbsp; &nbsp; ...(children .length ? {subNode: children} : {})显然,您不需要命名的助手,并且可以mapTree使用如下匿名函数进行调用:const myTransform = mapTree (&nbsp; (node) => node._children,&nbsp;&nbsp; (node, children) =>&nbsp;&nbsp; &nbsp; ({&nbsp; &nbsp; &nbsp; id: node.$id,&nbsp; &nbsp; &nbsp; text: node.name,&nbsp; &nbsp; &nbsp; icon: "fas fa-plus",&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; subNode: children&nbsp; &nbsp; }))这个mapTree函数很容易编写,因为我在编写它时不必考虑输出或输入格式的任何细节。但也许这种抽象对我没有帮助,除了这里我永远不会使用它。如果是这样,我可以通过直接插入硬编码回调来简单地重新设计抽象版本。只需稍加操作,即可将其变成这个版本:const newTransform = (node) =>&nbsp; ({&nbsp; &nbsp; id: node.$id,&nbsp; &nbsp; text: node.name,&nbsp; &nbsp; icon: "fas fa-plus",&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; subNode: (node._children || []).map(newTransform)&nbsp; })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))这里有一个重要的点。这个通用函数比我尝试编写一些东西来直接转换格式要容易得多。虽然过早的抽象存在危险,但它也可以提供显着的好处。我可能会选择只保留最后一个版本,但通用抽象简化了它的开发。
随时随地看视频慕课网APP

相关分类

JavaScript
我要回答