如何做递归树数组函数?
How to do recursive tree array function?
我有一个无限深的文件夹树状数组。每个文件夹都有一个“hasPermission”布尔值。我想要实现的是,当父文件夹(可以位于树中的任何位置)的“hasPermission”发生变化时,它的所有子文件夹“hasPermission”也会发生变化 - 当然,祖父文件夹“hasPermission”不会改变。
例如,在下面的文件夹树中。如果 folderId: '2.1' 更改权限, folderId: '3.1' 也会更改;其他的将保持不变。
const example = [
{
folderId: '1',
hasPermission: false,
children: [
{
folderId: '2.1',
hasPermission: false,
children: [
{
folderId: '3.1',
hasPermission: false,
children: [],
},
],
},
{
folderId: '2.2',
hasPermission: false,
children: [],
},
],
},
];
此函数递归地更改“hasPermission”。
const changeChildrenPermission = (
folders
) => {
return folders.map(
({ id, children, hasPermission }) => ({
id,
hasPermission: (hasPermission === false && true) || false,
children: changeChildrenPermission(children),
})
);
};
这是我目前所拥有的,我正在尝试查找 selectedId 的树,如果它
匹配,然后调用“changeChildrenPermission”函数。
const setPermissionChange = (
folders,
selectedId
) => {
const a = folders.map((folder) => {
if (folder.id === selectedId) {
return {
id: folder.folderId,
hasPermission: (hasPermission === false && true) || false,
children: changeChildrenPermission(folder.children),
};
});
};
不知道之后该做什么。
// visitFolders: Walks the folder tree recursively and calls visitFolder for every folder.
// - If visitFolder returns true for a folder, the walk stops immediately.
// - If you want to visit all folders, visitFolder should return false.
// (Returning false can be omitted, because the default return value of functions is undefined, which is falsy.)
const visitFolders = (folders, visitFolder) => {
for (let folder of folders) {
if (visitFolder(folder) || visitFolders(folder.children, visitFolder)) {
return true;
}
}
return false;
};
const findFolderById = (folders, id) => {
let folderWithId = null;
visitFolders(folders, folder => {
if (folder.id === id) {
folderWithId = folder;
return true;
}
return false;
});
return folderWithId;
};
const setFolderPermission = (folder, hasPermission) => {
visitFolders([folder], folder => {
folder.hasPermission = hasPermission;
return false;
});
};
const folders = [
{
id: "1",
hasPermission: true,
children: [
{
id: "1.1",
hasPermission: true,
children: []
},
{
id: "1.2",
hasPermission: true,
children: [
{
id: "1.2.1",
hasPermission: true,
children: []
},
{
id: "1.2.2",
hasPermission: true,
children: []
}
]
},
{
id: "1.3",
hasPermission: true,
children: []
},
{
id: "1.4",
hasPermission: true,
children: []
}
]
},
{
id: "2",
hasPermission: true,
children: [
{
id: "2.1",
hasPermission: true,
children: []
},
{
id: "2.2",
hasPermission: true,
children: []
}
]
}
];
const folder = findFolderById(folders, "1.2");
if (folder !== null) {
setFolderPermission(folder, false);
}
visitFolders(folders, folder => {
console.log(folder.id, folder.hasPermission);
return false;
});
我有一个无限深的文件夹树状数组。每个文件夹都有一个“hasPermission”布尔值。我想要实现的是,当父文件夹(可以位于树中的任何位置)的“hasPermission”发生变化时,它的所有子文件夹“hasPermission”也会发生变化 - 当然,祖父文件夹“hasPermission”不会改变。
例如,在下面的文件夹树中。如果 folderId: '2.1' 更改权限, folderId: '3.1' 也会更改;其他的将保持不变。
const example = [
{
folderId: '1',
hasPermission: false,
children: [
{
folderId: '2.1',
hasPermission: false,
children: [
{
folderId: '3.1',
hasPermission: false,
children: [],
},
],
},
{
folderId: '2.2',
hasPermission: false,
children: [],
},
],
},
];
此函数递归地更改“hasPermission”。
const changeChildrenPermission = (
folders
) => {
return folders.map(
({ id, children, hasPermission }) => ({
id,
hasPermission: (hasPermission === false && true) || false,
children: changeChildrenPermission(children),
})
);
};
这是我目前所拥有的,我正在尝试查找 selectedId 的树,如果它 匹配,然后调用“changeChildrenPermission”函数。
const setPermissionChange = (
folders,
selectedId
) => {
const a = folders.map((folder) => {
if (folder.id === selectedId) {
return {
id: folder.folderId,
hasPermission: (hasPermission === false && true) || false,
children: changeChildrenPermission(folder.children),
};
});
};
不知道之后该做什么。
// visitFolders: Walks the folder tree recursively and calls visitFolder for every folder.
// - If visitFolder returns true for a folder, the walk stops immediately.
// - If you want to visit all folders, visitFolder should return false.
// (Returning false can be omitted, because the default return value of functions is undefined, which is falsy.)
const visitFolders = (folders, visitFolder) => {
for (let folder of folders) {
if (visitFolder(folder) || visitFolders(folder.children, visitFolder)) {
return true;
}
}
return false;
};
const findFolderById = (folders, id) => {
let folderWithId = null;
visitFolders(folders, folder => {
if (folder.id === id) {
folderWithId = folder;
return true;
}
return false;
});
return folderWithId;
};
const setFolderPermission = (folder, hasPermission) => {
visitFolders([folder], folder => {
folder.hasPermission = hasPermission;
return false;
});
};
const folders = [
{
id: "1",
hasPermission: true,
children: [
{
id: "1.1",
hasPermission: true,
children: []
},
{
id: "1.2",
hasPermission: true,
children: [
{
id: "1.2.1",
hasPermission: true,
children: []
},
{
id: "1.2.2",
hasPermission: true,
children: []
}
]
},
{
id: "1.3",
hasPermission: true,
children: []
},
{
id: "1.4",
hasPermission: true,
children: []
}
]
},
{
id: "2",
hasPermission: true,
children: [
{
id: "2.1",
hasPermission: true,
children: []
},
{
id: "2.2",
hasPermission: true,
children: []
}
]
}
];
const folder = findFolderById(folders, "1.2");
if (folder !== null) {
setFolderPermission(folder, false);
}
visitFolders(folders, folder => {
console.log(folder.id, folder.hasPermission);
return false;
});