草庐IT

Javascript 从一组 URL 派生树

coder 2024-12-30 原文

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

我的问题

我的一组 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",
    }
];

我希望标题采用层次结构格式,我最终将以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 的子元素:[] 中,它们应该在 中>布的 child :[]

我使用的解决方案取自Here

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

最佳答案

逻辑如下。这是一个 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);

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

希望对你有帮助

关于Javascript 从一组 URL 派生树,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40945925/

有关Javascript 从一组 URL 派生树的更多相关文章

  1. ruby-on-rails - rails : save file from URL and save it to Amazon S3 - 2

    从给定URL下载文件并立即将其上传到AmazonS3的更直接的方法是什么(+将有关文件的一些信息保存到数据库中,例如名称、大小等)?现在,我既不使用Paperclip,也不使用Carrierwave。谢谢 最佳答案 简单明了:require'open-uri'require's3'amazon=S3::Service.new(access_key_id:'KEY',secret_access_key:'KEY')bucket=amazon.buckets.find('image_storage')url='http://www.ex

  2. ruby - 如何使用 Ruby aws/s3 Gem 生成安全 URL 以从 s3 下载文件 - 2

    我正在编写一个小脚本来定位aws存储桶中的特定文件,并创建一个临时验证的url以发送给同事。(理想情况下,这将创建类似于在控制台上右键单击存储桶中的文件并复制链接地址的结果)。我研究过回形针,它似乎不符合这个标准,但我可能只是不知道它的全部功能。我尝试了以下方法:defauthenticated_url(file_name,bucket)AWS::S3::S3Object.url_for(file_name,bucket,:secure=>true,:expires=>20*60)end产生这种类型的结果:...-1.amazonaws.com/file_path/file.zip.A

  3. ruby-on-rails - Ruby url 到 html 链接转换 - 2

    我正在使用Rails构建一个简单的聊天应用程序。当用户输入url时,我希望将其输出为html链接(即“url”)。我想知道在Ruby中是否有任何库或众所周知的方法可以做到这一点。如果没有,我有一些不错的正则表达式示例代码可以使用... 最佳答案 查看auto_linkRails提供的辅助方法。这会将所有URL和电子邮件地址变成可点击的链接(htmlanchor标记)。这是文档中的代码示例。auto_link("Gotohttp://www.rubyonrails.organdsayhellotodavid@loudthinking.

  4. ruby-on-rails - 如何生成传递一些自定义参数的 `link_to` URL? - 2

    我正在使用RubyonRails3.0.9,我想生成一个传递一些自定义参数的link_toURL。也就是说,有一个articles_path(www.my_web_site_name.com/articles)我想生成如下内容:link_to'Samplelinktitle',...#HereIshouldimplementthecode#=>'http://www.my_web_site_name.com/articles?param1=value1¶m2=value2&...我如何编写link_to语句“alàRubyonRailsWay”以实现该目的?如果我想通过传递一些

  5. ruby - Rack:如何将 URL 存储为变量? - 2

    我正在编写一个简单的静态Rack应用程序。查看下面的config.ru代码:useRack::Static,:urls=>["/elements","/img","/pages","/users","/css","/js"],:root=>"archive"map'/'dorunProc.new{|env|[200,{'Content-Type'=>'text/html','Cache-Control'=>'public,max-age=6400'},File.open('archive/splash.html',File::RDONLY)]}endmap'/pages/search.

  6. ruby-on-rails - Rails - 使用/自定义 URL : '/dashboard' 指定根路径 - 2

    如何使此根路径转到:“/dashboard”而不仅仅是http://example.com?root:to=>'dashboard#index',:constraints=>lambda{|req|!req.session[:user_id].blank?} 最佳答案 您可以通过以下方式实现:root:to=>redirect('/dashboard')match'/dashboard',:to=>"dashboard#index",:constraints=>lambda{|req|!req.session[:user_id].b

  7. python ffmpeg 使用 pyav 转换 一组图像 到 视频 - 2

    2022/8/4更新支持加入水印水印必须包含透明图像,并且水印图像大小要等于原图像的大小pythonconvert_image_to_video.py-f30-mwatermark.pngim_dirout.mkv2022/6/21更新让命令行参数更加易用新的命令行使用方法pythonconvert_image_to_video.py-f30im_dirout.mkvFFMPEG命令行转换一组JPG图像到视频时,是将这组图像视为MJPG流。我需要转换一组PNG图像到视频,FFMPEG就不认了。pyav内置了ffmpeg库,不需要系统带有ffmpeg工具因此我使用ffmpeg的python包装p

  8. ruby-on-rails - 使用 Dragonfly 从 URL 分配图像 - 2

    我正在使用Dragonfly在Rails3.1应用程序上处理图像。我正在努力通过url将图像分配给模型。我有一个很好的表格:{:multipart=>true}do|f|%>RemovePicture?Dragonfly的文档指出:Dragonfly提供了一个直接从url分配的访问器:@album.cover_image_url='http://some.url/file.jpg'但是当我在控制台中尝试时:=>#ruby-1.9.2-p290>picture.image_url="http://i.imgur.com/QQiMz.jpg"=>"http://i.imgur.com/QQ

  9. ruby-on-rails - 使用 javascript 更改数据方法不会更改 ajax 调用用户的什么方法? - 2

    我遇到了一个非常奇怪的问题,我很难解决。在我看来,我有一个与data-remote="true"和data-method="delete"的链接。当我单击该链接时,我可以看到对我的Rails服务器的DELETE请求。返回的JS代码会更改此链接的属性,其中包括href和data-method。再次单击此链接后,我的服务器收到了对新href的请求,但使用的是旧的data-method,即使我已将其从DELETE到POST(它仍然发送一个DELETE请求)。但是,如果我刷新页面,HTML与"new"HTML相同(随返回的JS发生变化),但它实际上发送了正确的请求类型。这就是这个问题令我困惑的

  10. ruby 正则表达式 : replace double slashes in URL - 2

    除了协议(protocol)定义中的斜杠('http[s]://'、'ftp://'等)之外,我想替换URL中的所有多个斜杠。我该怎么做?此代码无一异常(exception)地替换:url.gsub(/\/\/+/,'/') 最佳答案 您只需排除任何以:开头的匹配项url.gsub(/([^:])\/\//,'\1/') 关于ruby正则表达式:replacedoubleslashesinURL,我们在StackOverflow上找到一个类似的问题: http

随机推荐