【问题标题】:Javascript deriving a Tree from a set of URLs从一组 URL 派生一棵树的 Javascript
【发布时间】:2017-04-18 04:10:25
【问题描述】:

伙计们正在尝试创建一个动态菜单列表。用户可以创建的元素的深度没有限制。

我的问题

我的 URL 集是这样的

var json_data = [
    {
        "title" : "Food",
        "path" : "/root",
    },
    {
        "title" : "Cloths",
        "path" : "/root",
    },
    {
        "title" : "Veg",
        "path" : "/root/Food",
    },
    {
        "title" : "Brinjal",
        "path" : "/root/Food/Veg",
    },
    {
        "title" : "T shirt",
        "path" : "/root/Cloths",
    },
    {
        "title" : "Shirt",
        "path" : "/root/Cloths",
    },
    {
        "title" : "Green brinjal",
        "path" : "/root/Food/Veg/Brinjal",
    }
];

我希望titles 采用层次结构格式,我最终将以ul > li 的形式呈现以在前端创建菜单。

层次结构应该是这样的:

[
  {
    "title": "Food",
    "path": "/root",
    "children": [
      {
        "title": "Veg",
        "path": "/root/Food",
        "children": [
          {
            "title": "Brinjal",
            "path": "/root/Food/Veg",
            "children": [
              {
                "title": "Green brinjal",
                "path": "/root/Food/Veg/Brinjal",
                "children": []
              }
            ]
          }
        ]
      }
    ]
  },
  {
    "title": "Cloths",
    "path": "/root",
    "children": [
      {
        "title": "T shirt",
        "path": "/root/Cloths",
        "children": []
      },
      {
        "title": "Shirt",
        "path": "/root/Cloths",
        "children": []
      }
    ]
  }
]

我尝试了什么

    // Add an item node in the tree, at the right position
    function addToTree( node, treeNodes ) {
        // Check if the item node should inserted in a subnode
        for ( var i=0; i<treeNodes.length; i++ ) {
            var treeNode = treeNodes[i];
            // "/store/travel".indexOf( '/store/' )
            if ( node.path.indexOf( treeNode.path + '/' ) == 0 ) {
                addToTree( node, treeNode.children );
                // Item node was added, we can quit
                return;
            }
        }
        // Item node was not added to a subnode, so it's a sibling of these treeNodes
        treeNodes.push({
            title: node.title,
            path: node.path,
            children: []
        });
    }
    //Create the item tree starting from menuItems
    function createTree( nodes ){
        var tree = [];

        for ( var i=0; i<nodes.length; i++ ) {
            var node = nodes[i];
            addToTree( node, tree );
        }
        return tree;
    }

// variable = "json_data" is the set of URLS
var menuItemsTree = createTree( json_data );
console.log(menuItemsTree)

它产生的结果是这样的:

[
  {
    "title": "Food",
    "path": "/root",
    "children": [
      {
        "title": "Veg",
        "path": "/root/Food",
        "children": [
          {
            "title": "Brinjal",
            "path": "/root/Food/Veg",
            "children": [
              {
                "title": "Green brinjal",
                "path": "/root/Food/Veg/Brinjal",
                "children": []
              }
            ]
          }
        ]
      },
      {
        "title": "T shirt",
        "path": "/root/Cloths",
        "children": []
      },
      {
        "title": "Shirt",
        "path": "/root/Cloths",
        "children": []
      }
    ]
  },
  {
    "title": "Cloths",
    "path": "/root",
    "children": []
  }
]

元素 "T Shirt""Shirt" 被推入 Food's children:[] 中,这些元素应该在 Cloth's children:[]

我使用的解决方案取自Here

我试图自己推导出一个算法——但它还没有完全正确地点击。如果有人已经有解决方案,请提供帮助。如果我自己能得出一个解决方案,我会在这里分享。 上面的代码是 谢谢

【问题讨论】:

    标签: javascript json node.js


    【解决方案1】:

    下面是逻辑。这是一个Working Fiddle

    var json_data = [{
      "title": "Food",
      "path": "/root",
    }, {
      "title": "Cloths",
      "path": "/root",
    }, {
      "title": "Veg",
      "path": "/root/Food",
    }, {
      "title": "Brinjal",
      "path": "/root/Food/Veg",
    }, {
      "title": "T shirt",
      "path": "/root/Cloths",
    }, {
      "title": "Shirt",
      "path": "/root/Cloths",
    }, {
      "title": "Green brinjal",
      "path": "/root/Food/Veg/Brinjal",
    },{
      "title": "Test cloth",
      "path": "/root/Cloths/Shirt",
    }];
    
    
    // Add an item node in the tree, at the right position
    function addToTree(node, treeNodes) {
      var parentNode = GetTheParentNodeChildArray(node.path, treeNodes) || treeNodes;
    
      parentNode.push({
        title: node.title,
        path: node.path,
        children: []
      });
    }
    
    function GetTheParentNodeChildArray(path, treeNodes) {
      for (var i = 0; i < treeNodes.length; i++) {
        var treeNode = treeNodes[i];
    
        if (path === (treeNode.path + '/' + treeNode.title)) {
          return treeNode.children;
        } 
        else if (treeNode.children.length > 0) {
          var possibleParent = false;
    
          treeNode.children.forEach(function(item) {
            if (path.indexOf(item.path + '/' + item.title) == 0) {
              possibleParent = true;
              return false;
            }
          });
    
          if (possibleParent) {
            return GetTheParentNodeChildArray(path, treeNode.children)
          }
        }
      }
    }
    
    
    //Create the item tree starting from menuItems
    function createTree(nodes) {
      var tree = [];
    
      for (var i = 0; i < nodes.length; i++) {
        var node = nodes[i];
        addToTree(node, tree);
      }
      return tree;
    }
    
    // variable = "json_data" is the set of URLS
    var menuItemsTree = createTree(json_data);
    console.log(menuItemsTree);

    此逻辑的局限性: 如果父节点在子节点之前解析,则此逻辑有效,因此建议对列表进行排序 URL(即json_data[])同样如此。这是Sorting-before + tree-structuring-the-sorted的sn-p

    希望对你有帮助

    【讨论】:

    • 很抱歉,但是通过您的解决方案,“布料”本身正在进入“食物”内部,而“蔬菜”正在成为“食物”的兄弟姐妹
    • @SiddharthaChowdhury 哦,对不起。我没有测试..我会回复你..
    • @SiddharthaChowdhury 我正在研究它... :) 逻辑变得越来越难,因为您提到该级别可能会变得更深...现在这就是我的位置jsfiddle.net/10kLsxhz/2
    • 哦,好兄弟,感谢您付出了这么多努力。我也在尝试同样的方法:)
    • @SiddarthaChowdhury 是的,这是一个不完整的逻辑。我刚刚给你说我正在研究它..很高兴我能帮助你..这个问题也很有趣
    猜你喜欢
    • 2014-07-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多