我的需求是實現一個文件樹,需要對原始數據結構進行處理,返回前端需要的數據。
1、mongodb
數據庫中存放的原始數據:
let fData =
[
{
"pid": null,
"_id": "5e847c7f11228f1e88095dda",
"name": "公共資源"
},
{
"pid": "5e847c7f11228f1e88095dda",
"_id": "5e848a02b9d8b326ea4e2e0a",
"name": "文件夾一"
},
{
"pid": "5e847c7f11228f1e88095dda",
"_id": "5e8889473a9edb4235d98bae",
"name": "文件夾二"
},
{
"pid": "5e847c7f11228f1e88095dda",
"_id": "5e8889493a9edb4235d98baf",
"name": "文件夾三"
},
{
"pid": "5e8889493a9edb4235d98baf",
"_id": "5e8889563a9edb4235d98bb0",
"name": "檔案"
},
{
"pid": "5e8889493a9edb4235d98baf",
"_id": "5e8889663a9edb4235d98bb1",
"name": "音頻"
},
{
"pid": "5e8889493a9edb4235d98baf",
"_id": "5e88896c3a9edb4235d98bb2",
"name": "項目部"
}
]
2、需要將其轉化爲層級數據。
const getTreeData = (nodes) => {
nodes.forEach((ele: any) => {
// 名稱
ele.title = ele.name
ele.expand = true
ele.mode = 'show'
delete ele.name
let pid = ele.pid;
if (pid === null) {
// 是根元素的話 ,不做任何操作,如果是正常的for-i循環,可以直接continue.
} else {
// 如果ele是子元素的話 ,把ele扔到他的父親的child數組中.
nodes.forEach(d => {
if (d._id == pid) {
let childArray = d.children;
if (!childArray) {
childArray = [];
}
childArray.push(ele);
d.children = childArray;
}
});
}
});
// 去除重複元素
return nodes.filter(ele => ele.pid === null);
}
const tData = getTreeData(fOnes);
執行完之後,tData
爲:
[
{
"pid": null,
"_id": "5e847c7f11228f1e88095dda",
"title": "公共資源",
"expand": true,
"mode": "show",
"children": [
{
"pid": "5e847c7f11228f1e88095dda",
"_id": "5e848a02b9d8b326ea4e2e0a",
"title": "文件夾一",
"expand": true,
"mode": "show"
},
{
"pid": "5e847c7f11228f1e88095dda",
"_id": "5e8889473a9edb4235d98bae",
"title": "文件夾二",
"expand": true,
"mode": "show"
},
{
"pid": "5e847c7f11228f1e88095dda",
"_id": "5e8889493a9edb4235d98baf",
"title": "文件夾三",
"expand": true,
"mode": "show",
"children": [
{
"pid": "5e8889493a9edb4235d98baf",
"_id": "5e8889563a9edb4235d98bb0",
"title": "檔案",
"expand": true,
"mode": "show"
},
{
"pid": "5e8889493a9edb4235d98baf",
"_id": "5e8889663a9edb4235d98bb1",
"title": "音頻",
"expand": true,
"mode": "show"
},
{
"pid": "5e8889493a9edb4235d98baf",
"_id": "5e88896c3a9edb4235d98bb2",
"title": "項目部",
"expand": true,
"mode": "show"
}
]
}
]
}
]
3、根據層級數據和一個子結點,獲取父節點信息
const folder_id = '5e8889493a9edb4235d98baf';
// 定義數組,用於存放
let arr = [];
const getParentsIds = (data) => {
for (let i = 0; i < data.length; i++) {
let temp = data[i]
if (temp._id == folder_id) {
arr.push(temp._id);
return 1
}
if (temp && temp.children && temp.children.length > 0) {
let t = getParentsIds(temp.children)
if (t == 1) {
arr.push(temp._id)
return 1
}
}
}
}
getParentsIds(tData)
輸出的arr
爲
[ '5e8889493a9edb4235d98baf', '5e847c7f11228f1e88095dda' ]
4、根據原始數據和一個子結點,獲取父節點信息
const fnode = {
"pid": "5e8889493a9edb4235d98baf",
"_id": "5e8889563a9edb4235d98bb0",
"title": "檔案",
"expand": true,
"mode": "show"
};
const findP = (nodes, node) => {
const ans = [];
for (let i = 0; i < nodes.length; i++) {
if (node.pid == nodes[i]._id) {
ans.push(nodes[i]);
return ans.concat(findP(nodes, nodes[i]));
}
}
}
const pOnes = findP(fOnes, fnode).filter(x => {return x});
返回結果如下:
[
{
"pid": "5e847c7f11228f1e88095dda",
"_id": "5e8889493a9edb4235d98baf",
"name": "文件夾三"
},
{
"pid": null,
"_id": "5e847c7f11228f1e88095dda",
"name": "公共資源"
}
]
5、根據原始數據和一個子結點,獲取這個子結點下的子樹
const fnode = {
"pid": "5e847c7f11228f1e88095dda",
"_id": "5e8889493a9edb4235d98baf",
"title": "文件夾三"
};
//找子節點
const findC = (nodes, node) => {
let ans = [];
for (let i = 0; i < nodes.length; i++) {
if (node._id == nodes[i].pid) {
ans.push(nodes[i]);
ans = ans.concat(findC(nodes, nodes[i]));
}
}
return ans;
}
const cOnes = findC(fOnes, fnode);
此時cOnes
中數據爲
[
{
"pid": "5e8889493a9edb4235d98baf",
"_id": "5e8889563a9edb4235d98bb0",
"name": "檔案"
},
{
"pid": "5e8889493a9edb4235d98baf",
"_id": "5e8889663a9edb4235d98bb1",
"name": "音頻"
},
{
"pid": "5e8889493a9edb4235d98baf",
"_id": "5e88896c3a9edb4235d98bb2",
"name": "項目部"
}
]