Javascript 将平面阵列转换为树结构

Javascript 将平面阵列转换为树结构,javascript,ecmascript-6,Javascript,Ecmascript 6,我有一个从MySQL查询得到的平面数组,但我需要将其转换为树结构。我已经试着做了一段时间了,但似乎无法完成 它基本上是用于web应用程序中的导航。某些节点将具有子节点,但其他节点将不具有子节点 我尝试过使用ES6数组函数,如reduce、map等,但无法显示子元素 这是结构图 [ { "page_id": 1, "page_name": "dashboard", "path": "/", "page_icon": "dashboard", "sub_p

我有一个从MySQL查询得到的平面数组,但我需要将其转换为树结构。我已经试着做了一段时间了,但似乎无法完成

它基本上是用于web应用程序中的导航。某些节点将具有子节点,但其他节点将不具有子节点

我尝试过使用ES6数组函数,如reduce、map等,但无法显示子元素

这是结构图

[
  {
    "page_id": 1,
    "page_name": "dashboard",
    "path": "/",
    "page_icon": "dashboard",
    "sub_page_id": 0,
    "sub_page_name": null,
    "sub_page_path": null,
    "sub_page_icon": null,
    "parent_id": 0
  },
  {
    "page_id": 2,
    "page_name": "Transactions",
    "path": "/transactions",
    "page_icon": "swap_horiz",
    "sub_page_id": 0,
    "sub_page_name": null,
    "sub_page_path": null,
    "sub_page_icon": null,
    "parent_id": 0
  },
  {
    "page_id": 6,
    "page_name": "Reports",
    "path": null,
    "page_icon": null,
    "sub_page_id": 1,
    "sub_page_name": "Transactions Value",
    "sub_page_path": "/transactions-value",
    "sub_page_icon": "assessment",
    "parent_id": 6
  },
  {
    "page_id": 6,
    "page_name": "Reports",
    "path": null,
    "page_icon": null,
    "sub_page_id": 2,
    "sub_page_name": "Transactions Volume",
    "sub_page_path": "/transactions-volume",
    "sub_page_icon": "assessment",
    "parent_id": 6
  },
  {
    "page_id": 6,
    "page_name": "Reports",
    "path": null,
    "page_icon": null,
    "sub_page_id": 3,
    "sub_page_name": "Transactions Frequency",
    "sub_page_path": "/transactions-frequency",
    "sub_page_icon": "assessment",
    "parent_id": 6
  },
  {
    "page_id": 8,
    "page_name": "Holidays",
    "path": null,
    "page_icon": null,
    "sub_page_id": 7,
    "sub_page_name": "My Holidays",
    "sub_page_path": "/my-holidays",
    "sub_page_icon": "wb_sunny",
    "parent_id": 8
  },
  {
    "page_id": 8,
    "page_name": "Holidays",
    "path": null,
    "page_icon": null,
    "sub_page_id": 8,
    "sub_page_name": "Add User",
    "sub_page_path": "/add-user",
    "sub_page_icon": "person_add",
    "parent_id": 8
  },
  {
    "page_id": 8,
    "page_name": "Holidays",
    "path": null,
    "page_icon": null,
    "sub_page_id": 9,
    "sub_page_name": "Add Site",
    "sub_page_path": "/add-site",
    "sub_page_icon": "location_on",
    "parent_id": 8
  },
  {
    "page_id": 10,
    "page_name": "Logout",
    "path": "/logout",
    "page_icon": "input",
    "sub_page_id": 0,
    "sub_page_name": null,
    "sub_page_path": null,
    "sub_page_icon": null,
    "parent_id": 0
  }
]

就在我头顶上,你可以用一个


伙计们,我已经做到了。可能不是最有效的方法,但它很有效

const data = response.data;
const tree = [];

data.reduce(function(a, b, i, r) {

    // Add the parent nodes
    if(a.page_id != b.page_id){
        tree.push({ page_id: a.page_id,
                        page_name: a.page_name,
                        page_path: a.path,
                        page_icon: a.page_icon
                    });
    }

    // Add the last parent node
    if(i+1 == data.length) {
        tree.push({ page_id: b.page_id,
                        page_name: b.page_name,
                        page_path: b.path,
                        page_icon: b.page_icon
                    });

        // Add the child nodes to the parent nodes
        data.reduce(function(a, b) {
            if(a.sub_page_id) {
                const find = tree.findIndex(f => f.page_id == a.parent_id);

                // Add the first child node to parent
                if(!("children" in tree[find])) {
                    tree[find].children = [];

                    tree[find].children.push({ page_id: a.sub_page_id,
                                                page_name: a.sub_page_name,
                                                page_path: a.sub_page_path,
                                                page_icon: a.sub_page_icon
                    });
                }
                // Add the remaining child nodes to parent nodes
                else {
                    tree[find].children.push({ page_id: a.sub_page_id,
                                                page_name: a.sub_page_name,
                                                page_path: a.sub_page_path,
                                                page_icon: a.sub_page_icon
                    });
                }
            }
            return b;
        });
    }
    return b;
});

请添加文字符号中的数据和您尝试过的内容,以及结果。嗨@NinaScholz,我已经为您完成了。我记得不久前你帮我解决了一个类似的问题。如果你能再帮我一把,我将不胜感激。并不是所有的数据都在那里,因为Stackoverflow不允许,但基本结构在那里。为什么您有相同的
页面id
父id
?请同时添加想要的结果。您好@NinaScholz,如果您查看该表,这是两个连接在一起的表(pages&sub_pages table)。parent_id是引用pages表的外键,因此子页“Transactions Value”是“Reports”的子页。我希望报告、假日、演示和工具只出现一次,sub_pages表中的所有内容都是父节点id修补程序页面id.ok所在节点的子节点。但看不到结果。这不是工作伙伴。获取“无法读取未定义的属性‘push’”。您在哪里看到一个
push
?此外,这并不是复制/粘贴解决方案。只是为了让你开始。如果在您尝试将子道具附加到对象上之前,对象中不存在父道具,则此操作无疑会失败。太好了。但遗憾的是,由于缺少结果,我们无能为力。
const data = response.data;
const tree = [];

data.reduce(function(a, b, i, r) {

    // Add the parent nodes
    if(a.page_id != b.page_id){
        tree.push({ page_id: a.page_id,
                        page_name: a.page_name,
                        page_path: a.path,
                        page_icon: a.page_icon
                    });
    }

    // Add the last parent node
    if(i+1 == data.length) {
        tree.push({ page_id: b.page_id,
                        page_name: b.page_name,
                        page_path: b.path,
                        page_icon: b.page_icon
                    });

        // Add the child nodes to the parent nodes
        data.reduce(function(a, b) {
            if(a.sub_page_id) {
                const find = tree.findIndex(f => f.page_id == a.parent_id);

                // Add the first child node to parent
                if(!("children" in tree[find])) {
                    tree[find].children = [];

                    tree[find].children.push({ page_id: a.sub_page_id,
                                                page_name: a.sub_page_name,
                                                page_path: a.sub_page_path,
                                                page_icon: a.sub_page_icon
                    });
                }
                // Add the remaining child nodes to parent nodes
                else {
                    tree[find].children.push({ page_id: a.sub_page_id,
                                                page_name: a.sub_page_name,
                                                page_path: a.sub_page_path,
                                                page_icon: a.sub_page_icon
                    });
                }
            }
            return b;
        });
    }
    return b;
});