我需要檢查 的值是否url存在于path以下樹的任何物件或節點的屬性中。
關于樹。該children屬性是可選的,但如果存在,則可以無限期擴展
該樹看起來類似于以下內容
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 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);
但我注意到,當添加一個新節點(如樹示例中的注釋節點)時,例如作為第一個節點的子節點,它不會評估父節點之后的節點。
另外,遞回對我來說通常很困難,所以我很感激你的建議。
提前致謝
uj5u.com熱心網友回復:
在你的函式中,你回傳true或者false回傳具有匹配路徑或具有子項的每個條目。使用當前代碼繼續迭代的唯一方法是不匹配并且沒有孩子。
我建議簡化一下以便更清楚:
function isValid(url, tree) {
return tree.some(item =>
item.path === url || (item.children && isValid(url, item.children))
);
}
uj5u.com熱心網友回復:
“但我注意到,當添加一個新節點(如樹示例中的注釋節點)時,例如作為第一個節點的子節點,它不會評估父節點之后的節點。”
這是你的罪魁禍首:
/*
|| Without that extra >children< property, the function goes on to find
|| the given search term
*/
if (!node.children) {
continue;
}
/*
|| But with that extra >children< property on the way the function is
|| forced to continue onto this snafu. Since the extra >children<
|| property returns as false from isValid(), the control statement
|| is skipped and goes to the last line which is return false. So the
|| function terminates because a return statement always terminates the
|| function thereby never reaching the end of the array.
*/
const found = isValid(url, node.children);
if (found) {
return found;
}
/*
|| Do not use a return within a "for" loop. If it is reached then most
|| likely the function terminates too early and the loop never continues
|| onto the next iteration.
*/
return false;
}
詳細資訊在示例中進行了注釋
const admin = [{
title: "Dashboard",
path: "/admin/dashboard",
items: [{
title: "Dashboard Reports",
path: "/admin/dashboard/reports"
}]
},
{
title: "Management",
path: "/admin/management",
items: [{
title: "Management Reports",
path: "/admin/management/reports"
}]
},
{
title: "Archive",
path: "/admin/archive",
items: [{
title: "Archive Reports",
path: "/admin/archive/reports",
items: [{
title: "Archive Reports Management",
path: "/admin/archive/reports/management"
}, {
title: "Archive Reports Dashboard",
path: "/admin/archive/reports/dashboard"
}]
}]
}
];
/**
* Searches for a given string within each object's >path< property value of a
* given array of objects.
* @param {String} term - The string segment to search for.
* @param {Array<object>} struct - The array of objects to search through
* @returns {Array<array>} - An array of arrays that contain the value of each
* >path< property that has >term< within it.
*/
function searchStruct(term, struct) {
let data = []; // 1
if (Array.isArray(struct)) {
for (const node of struct) {
if (node.path.includes(term)) {
data.push(node.path); // 2
}
if (node.items) {
data.push(searchStruct(term, node.items)); // 3
}
}
}
return data; // 4
}
console.log(searchStruct("reports", admin));
/**
* If you just want a simple true/false returned, replace the line at
* 1 with: (remove line)
* 2 with: return true;
* 3 with: if (searchStruct(term, node.items)) return true;
* 4 with: return false;
*/
要使函式遞回,它必須:
- 說明它將呼叫自身的條件
if (node.items) { data.push(searchStruct(term, node.items)); } - 必須迭代此條件(在回圈、陣列方法等內)
- 有一個遞回呼叫的函式傳遞的新值
searchStruct(term, node.items) // New value passed ??
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/537101.html
標籤:javascript递归
上一篇:如何搜索基于物件的樹?
