我的需求是实现一个文件树,需要对原始数据结构进行处理,返回前端需要的数据。
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.nameele.expand = trueele.mode = 'show'delete ele.namelet 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": "项目部"}
]