繁体   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