javascript - Javascript - 寻找一种转换父子关系的方法
问题描述
我在转换父子关系时遇到问题。截至目前,我的数据结构如下所示。
{
"id": 7,
"name": "Folder 1",
"parent_folder": null,
"folders": [
{
"id": 8,
"name": "Folder 1-1",
"parent_folder": 7
},
{
"id": 10,
"name": "Folder 1-2",
"parent_folder": 7
}
],
},
{
"id": 8,
"name": "Folder 1-1",
"parent_folder": 7,
"folders": [
{
"id": 9,
"name": "Folder 1-1-1",
"parent_folder": 8
}
],
},
{
"id": 9,
"name": "Folder 1-1-1",
"parent_folder": 8,
}
每个文件夹都有自己的表示,您可以在其中找到 parent_folder id 及其子项(仅向下一层)。
复杂性是当我尝试更深入地了解结构时。我可以创建如下结构:
Folder 1
Folder 1-1
Folder 1-2
但是当我尝试添加文件夹 1-1-1时,它让我失败了。
我想出的解决方案可以在下面找到。我从 API 端点获取此文件夹数据,并尝试仅处理该响应。检索到响应后,代码片段就出现了:
var tempFolderList = [];
var f = response.data.folders;
for (var folder in f) {
if (f[folder].parent_folder) {
console.log("PARENT TEMPLATE FOLDER FOUND");
// Create temporary variable
var tempChildFolder = {
id: f[folder].id,
name: f[folder].name,
parent_folder: f[folder].parent_folder,
children: [],
};
var attv = this.addToTree(tempFolderList, folder, tempChildFolder, f)
console.log("attv: " + attv)
if (attv) {
this.tempFolderList = attv
}
else {
tempFolderList.push(tempChildFolder)
}
// Check if id from current iteration is in temp Folder list
// if yes add to the list, if not :TODO:
// if (
// tempFolderList.find(
// (x) => x.id === f[folder].parent_folder
// )
// ) {
// tempFolderList
// .find((x) => x.id === f[folder].parent_folder)
// .children.push(tempChildFolder);
// }
} else {
// If folder do not have parent folder, just add to temp folder list
var tempFolder = {
id: f[folder].id,
name: f[folder].name,
parent_folder: f[folder].parent_folder,
children: [],
};
tempFolderList.push(tempFolder);
}
console.log(tempFolderList);
}
这是 addToTree 函数:
addToTree(tempFolderList, folder, tempChildFolder, folderList) {
if (tempFolderList.find((x) => x.id === folderList[folder].parent_folder)) {
// tempFolderList.find((x) => x.id === f[folder].parent_folder).children.push(tempChildFolder)
tempFolderList.push(tempChildFolder)
return tempFolderList;
}
else {
for (var f in tempFolderList) {
var attt = this.addToTree(tempFolderList[f].children, folder, tempChildFolder, folderList)
if (attt) {
tempFolderList[f] = attt
return tempFolderList
}
else {
return false
}
}
}
},
解决方案
首先,使用其 id 创建一个文件夹映射,以便以后更快地访问:
let folders = response.data.folders
let folderMap = folders.reduce((map, folder) => {
map[folder.id] = folder
return map
}, {})
然后只过滤根文件夹:
let folderTree = folders.filter(folder => folder.parent_folder === null)
然后递归解析文件夹子项:
let resolveFolder = function (folder) {
let newFolder = { ...folderMap[folder.id] } // shallow copy the folder object here because of the next line we will mutate it
if (newFolder.folders) {
newFolder.folders = newFolder.folders.map(resolveFolder)
}
return newFolder
}
folderTree.map(resolveFolder)
let folders = [
{
"id": 7,
"name": "Folder 1",
"parent_folder": null,
"folders": [
{
"id": 8,
"name": "Folder 1-1",
"parent_folder": 7
},
{
"id": 10,
"name": "Folder 1-2",
"parent_folder": 7
}
]
},
{
"id": 8,
"name": "Folder 1-1",
"parent_folder": 7,
"folders": [
{
"id": 9,
"name": "Folder 1-1-1",
"parent_folder": 8
}
]
},
{
"id": 9,
"name": "Folder 1-1-1",
"parent_folder": 8
},
{
"id": 10,
"name": "Folder 1-2",
"parent_folder": 7
}
]
let folderMap = folders.reduce((map, folder) => {
map[folder.id] = folder
return map
}, {})
let resolveFolder = function (folder) {
return {
...folderMap[folder.id],
folders: folderMap[folder.id].folders?.map(resolveFolder)
}
}
let folderTree = folders
.filter(folder => folder.parent_folder === null)
.map(resolveFolder)
console.log(folderTree)
推荐阅读
- node.js - MongoDB 向 NodeJS 中的现有用户插入数据
- sql - 动态 sql - 使用循环更新多行
- excel - Office js 多页加载项导航
- generics - Rust:缩短泛型类型界限
- windows - 来自 docker-compose 的 Docker 容器无法再连接到主机
- fonts - NativeScript:字体未在 Android 上加载
- reactjs - 如何在 ReactJS 中获取当前组件的名称?
- postgresql - 如何在 ubuntu 服务器上安装 postgis?
- c# - c# 只允许加载签名的程序集
- php - 制作while循环PHP?