I need to check if the value of url
exists within the path
property in any of the objects or nodes of the following tree.
Regarding the tree. The children
property is optional but if it exists it could be expanded indefinitely
The tree looks similar to the following
const items = [
{
path: "/admin/dashboard",
menuIcon: {
icon: "dashboard",
title: "toolbar.dashboard",
},
// children: [
// {
// path: "/admin/collection",
// menuIcon: {
// icon: "summarize",
// title: "toolbar.reports",
// },
// },
// ],
},
{
path: "/admin/contents",
menuIcon: {
icon: "archive",
title: "toolbar.contents",
},
},
{
path: "/admin/cigar-house-management",
menuIcon: {
icon: "home",
title: "toolbar.directory-management",
},
children: [
{
path: "/admin/reports",
menuIcon: {
icon: "summarize",
title: "toolbar.reports",
},
children: [
{
path: "/admin/admin-reports",
menuIcon: {
icon: "summarize",
title: "toolbar.reports",
},
},
],
},
],
},
];
In order to achieve the desired result I am using the following function
function isValid(url, tree) {
if (tree && Array.isArray(tree) && tree.length > 0) {
for (const node of tree) {
if (node.path === url) {
return true;
}
if (!node.children) {
continue;
}
const found = isValid(url, node.children);
if (found) {
return found;
}
return false;
}
}
}
Can be checked here
const url = "/admin/admin-reports";
const items = [
{
path: "/admin/dashboard",
menuIcon: {
icon: "dashboard",
title: "toolbar.dashboard",
},
// children: [
// {
// path: "/admin/collection",
// menuIcon: {
// icon: "summarize",
// title: "toolbar.reports",
// },
// },
// ],
},
{
path: "/admin/contents",
menuIcon: {
icon: "archive",
title: "toolbar.contents",
},
},
{
path: "/admin/cigar-house-management",
menuIcon: {
icon: "home",
title: "toolbar.directory-management",
},
children: [
{
path: "/admin/reports",
menuIcon: {
icon: "summarize",
title: "toolbar.reports",
},
children: [
{
path: "/admin/admin-reports",
menuIcon: {
icon: "summarize",
title: "toolbar.reports",
},
},
],
},
],
},
];
function isValid(url, tree) {
if (tree && Array.isArray(tree) && tree.length > 0) {
for (const node of tree) {
if (node.path === url) {
return true;
}
if (!node.children) {
continue;
}
const found = isValid(url, node.children);
if (found) {
return found;
}
return false;
}
}
}
const output = isValid(url, items);
console.log(output);
But I have noticed that when adding a new node (like the commented node in the tree example), for example as a child of the first node, it does not evaluate the ones after the parent node and likewise
I don't get along with recursion so I would appreciate your advice
Recursion is usually difficult for me so I would appreciate your advice.
Thanks in advance
CodePudding user response:
In your function, you're returning either true
or false
for every entry that either has a matching path, or has children. The only way to continue the iteration with your current code is to not match and not have children.
I'd recommend simplifying a bit so it's clearer:
function isValid(url, tree) {
return tree.some(item =>
item.path === url || (item.children && isValid(url, item.children))
);
}