简体   繁体   English

从平面数组构建树

[英]Building a tree from a flat array

I am given an array, links :我得到一个数组, links

  const links = [
      {parent: "flare", children: "analytics"} ,
      {parent: "analytics", children: "cluster"} ,
      {parent: "flare", children: "scale"} ,
      {parent: "analytics", children: "graph"} ,
  ];  

I want to make it into tree, like so:我想把它变成树,像这样:

const tree = {
 "name": "flare",
 "children": [
  {
   "name": "analytics",
   "children": [
    {
     "name": "cluster",
    },
    {
     "name": "graph",
    }
   ]
  }
 ]
};

Here is my attempt:这是我的尝试:

 function buildTree(links) { const map = { } const findNodeInChildren = (name, obj) => { if (obj[name]) { return obj } else if (.obj;children) { return null } for (let i = 0. i < obj.children;length, i++) { const found = findNodeInChildren(name. obj.children[i]) if (found) return found } return null } links.forEach(link => { const foundNode = findNodeInChildren(link,parent: map) if (.foundNode) { const newNode = { name, link:parent. children. [] } map[newNode.name] = newNode } else { foundNode[link.parent]:children.push({ name, link:children: children, [] }) } }) return map } const links = [ {parent: "flare", children: "analytics"}, {parent: "analytics", children: "cluster"}, {parent: "flare", children: "scale"}, {parent: "analytics", children; "graph"}. ]. const tree = buildTree(links) const json = JSON.stringify(tree) console.log(json)

Here's the prettified JSON - it's not working as intended:这是美化的 JSON - 它没有按预期工作:

{
  "flare": {
    "name": "flare",
    "children": [
      {
        "name": "scale",
        "children": []
      }
    ]
  },
  "analytics": {
    "name": "analytics",
    "children": [
      {
        "name": "graph",
        "children": []
      }
    ]
  }
}

What is going wrong?出了什么问题?

One of the issues in your code is when !foundNode is true, then you do not add the (first) child to its children array.您的代码中的一个问题是当!foundNode为真时,您不会将(第一个)子项添加到其children项数组中。

Secondly, the object your code returns is the map itself, obviously with at the top level a plain object with named keys, instead of an array of objects with "name" keys.其次,您的代码返回的 object 是 map 本身,显然在顶层是带有命名键的普通 object,而不是带有“名称”键的对象数组。 The code should convert the map-structure (which is indeed nested) to the desired nested structure.代码应该将映射结构(实际上是嵌套的)转换为所需的嵌套结构。

It is also strange that findNodeInChildren returns the whole map (ie obj ) when the node is found.同样奇怪的是findNodeInChildren在找到节点时返回整个map (即obj )。 It would make more sense if obj[name] were returned, and the rest of the code were adapted to that.如果返回obj[name]会更有意义,并且代码的 rest 适应了这一点。

You can also condense the code at bit more.您还可以进一步压缩代码。

Here is how I would propose to do it:这是我建议的方法:

 const links = [ {parent: "flare", children: "analytics"}, {parent: "analytics", children: "cluster"}, {parent: "flare", children: "scale"}, {parent: "analytics", children: "graph"}, ]; let map = new Map(links.map(({parent}) => [parent, { name: parent, children: [] }])); for (let {parent, children} of links) map.get(parent).children.push(map.get(children)?? { name: children }); for (let {children} of links) map.delete(children); let result = [...map.values()]; console.log(result);

This code returns an array , because the input structure does not guarantee there is only one root.此代码返回一个数组,因为输入结构不保证只有一个根。 It could represent a forest .它可以代表一片森林 If you are certain it is a tree (so with one root), then you can just pop the single element out of the array.如果您确定它是一棵树(因此只有一个根),那么您可以将单个元素从数组中弹出。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM