Get the Tree Menu Node Path
Question
There is a tree structure menu that supports unlimited nesting levels. It is necessary to obtain the path of the node where the submenu is located according to a certain submenu that the user clicks, which is similar to the breadcrumb effect.
A qualified tree menu data structure
const menu = [
{
id: "1",
label: "Level 1",
children: [
{
id: "11",
label: "Level 2 1-1",
children: [
{
id: "111",
label: "Level 3 1-1-1",
},
],
},
],
},
{
id: "2",
label: "Level 1 2",
children: [
{
id: "21",
label: "Level 2 2-1",
children: [
{
id: "211",
label: "Level 3 2-1-1",
},
],
},
{
id: "22",
label: "Level 2 2-2",
children: [
{
id: "221",
label: "Level 3 2-2-1",
},
],
},
],
},
{
id: "3",
label: "Level 1 3",
children: [
{
id: "31",
label: "Level 2 3-1",
children: [
{
id: "311",
label: "Level 3 3-1-1",
},
],
},
{
id: "32",
label: "Level 2 3-2",
children: [
{
id: "321",
label: "Level 3 3-2-1",
},
],
},
],
},
];
Solution
Analysis:
Recurse the entire tree menu, record the current path name each time it loops, and concatenate all the node names after matching.
One of the key processing points is that every time you loop to the same level array, you need to start recording the path again, otherwise the path will be repeated.
Code:
/**
* @param {array[][]} data the entire menu array
* @param {object[][]} v current node object
* @return {string[]} The path of the current node object
*/
function findPath(data, v) {
var find = false; //Mark after finding id, end recursion
var paths = [];
findId(data, v.id);
return paths.join("/");
function findId(root, vid) {
var currentPathsLength = paths.length;
root.forEach((ele, i, root) => {
//Has been found, no need to deal with the following logic
if (find) {
return;
}
// Loop to the same level array each time and start recording the path again
paths = paths.slice(0, currentPathsLength);
paths.push(ele.label);
// Find and return
if (ele.id === vid) {
find = true;
return;
} else if (Array.isArray(ele.children) && ele.children.length > 0) {
//Continue to find child nodes
return findId(ele.children, vid);
}
});
}
}
Online Demo:
Comments