/**
* @param {Array} sourceData 原始数据(必选)
* @param {String} keyName 单条数据中的唯一标识符字段名(必选)
* @param {String} parentKeyName 单条数据中的上级唯一标识符的字段名(必选)
* @return {Array} Tree树结构
*/
function toTree({ sourceData, keyName, parentKeyName }) {
let result = [];
// 传入数据不是数组直接return
if (!Array.isArray(sourceData)) {
alert("传入的原始数据需为数组...");
return result;
}
if (!keyName || typeof keyName != "string") {
alert("未传入本身唯一标识符字段名或传入字段名不为字符串...");
return result;
}
if (!parentKeyName || typeof parentKeyName != "string") {
alert("未传入上级唯一标识符字段名或传入字段名不为字符串...");
return result;
}
let map = new Map();
sourceData.forEach((item) => {
// delete item.children; // 如每条数据中的children无用可直接删除
map.set(item[keyName], item);
});
sourceData.forEach((item) => {
let parent = map.get(item[parentKeyName]);
if (parent) {
(parent.children || (parent.children = [])).push(item);
} else {
result.push(item);
}
});
return result;
}
export default toTree
测试数据,无上级时可无parent_id字段(如测试0与测试5),或为null(如测试3)、或为空(如测试4):
let list = [
{
id: 0,
name: "测试0",
},
{
id: 1,
name: "测试1",
parent_id: 0,
},
{
id: 2,
name: "测试2",
parent_id: 1,
},
{
id: 3,
name: "测试3",
parent_id: null,
},
{
id: 4,
name: "测试4",
parent_id: "",
},
{
id: 5,
name: "测试5",
},
]
调用:
let data = {
sourceData: list,
keyName: "id",
parentKeyName: "parent_id",
}
let tree_data = toTree(data)
console.log(tree_data)
结果:
[
{
"id": 0,
"name": "测试0",
"children": [
{
"id": 1,
"name": "测试1",
"parent_id": 0,
"children": [
{
"id": 2,
"name": "测试2",
"parent_id": 1
}
]
}
]
},
{
"id": 3,
"name": "测试3",
"parent_id": null
},
{
"id": 4,
"name": "测试4",
"parent_id": ""
},
{
"id": 5,
"name": "测试5"
}
]