繁体   English   中英

从平面数组构建一棵树

[英]Build a Tree from Flat Array

这是一个由 API 返回的列表,需要将其转换为可以显示的树,以便用户可以 select 获得所需的权限。

const list = [
{
    resource: 'User',
    action: 'Create',
    id: 1,
},
{
    resource: 'User',
    action: 'Edit',
    id: 2,
},
{
    resource: 'User',
    action: 'Delete',
    id: 3,
},
{
    resource: 'Utility.Rule',
    action: 'Create',
    id: 4,
},
{
    resource: 'Utility.Rule',
    action: 'Edit',
    id: 5,
},
{
    resource: 'Utility.Config',
    action: 'Create',
    id: 6,
},

];

并且需要转换成一棵树

    {
  "id": "root",
  "name": "MyTree",
  "children": [
    {
      "id": "User",
      "name": "User",
      "children": [
        {
          "id": "1",
          "name": "Create"
        },
        {
          "id": "2",
          "name": "Edit"
        },
        {
          "id": "3",
          "name": "Delete"
        }
      ]
    },
    {
      "id": "Utility",
      "name": "Utility",
      "children": [
        {
          "id": "Rule",
          "name": "Rule",
          "Children": [
            {
              "id": "4",
              "name": "Create"
            },
            {
              "id": "5",
              "name": "Edit"
            }
          ]
        },
        {
          "id": "Config",
          "name": "Config",
          "children": [
            {
              "id": "6",
              "name": "Create"
            }
          ]
        }
      ]
    }
  ]
}

我尝试了不同的方法,如 Map 并减少但没有得到想要的 output。

const arrayToTree = (arr, parent = 'User') =>
  arr.filter(item => item.parent === parent)
     .map(child => ({ ...child, children: arrayToTree(arr, 
     child.index) }));

arrayToTree(list, 'User')

//This gives me stackoverflow error.

我尝试的其他选项是首先构建 map

function list_to_tree(list) {
  var map = {}, node, roots = [], i;
  
  for (i = 0; i < list.length; i += 1) {
    map[list[i].id] = i; // initialize the map
    list[i].children = []; // initialize the children
  }
  
  for (i = 0; i < list.length; i += 1) {
    node = list[i];
    if (node.parentId !== "0") {
      // if you have dangling branches check that map[node.parentId] exists
      list[map[node.parentId]].children.push(node);
    } else {
      roots.push(node);
    }
  }
  return roots;
}

如果我能对如何构造主节点然后添加子节点有所了解,那就太好了。

我想出的解决方案是遍历列表,用“。”分割每个资源。 如果不在父节点的子节点中,则为每个资源目录添加一个节点

 const list = [ { resource: 'User', action: 'Create', id: 1 }, { resource: 'User', action: 'Edit', id: 2 }, { resource: 'User', action: 'Delete', id: 3 }, { resource: 'Utility.Rule', action: 'Create', id: 4 }, { resource: 'Utility.Rule', action: 'Edit', id: 5 }, { resource: 'Utility.Config', action: 'Create', id: 6 }, ]; function arrayToTree(list, rootNode = { id: 'root', name: 'MyTree' }) { const addChild = (node, child) => ((node.children?? (node.children = [])).push(child), child); for (const { id, action, resource } of list) { const path = resource.split('.'); const node = path.reduce( (currentNode, targetNodeId) => currentNode.children?.find(({ id }) => id === targetNodeId)?? addChild(currentNode, { id: targetNodeId, name: targetNodeId }), rootNode ); addChild(node, { id: String(id), name: action }); } return rootNode; } console.log(arrayToTree(list));

暂无
暂无

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

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