/** * @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" } ]