扁平数据结构转Tree
看了
#稀土掘金文章#面试了十几个高级前端,竟然连(扁平数据结构转Tree)都写不出来 后,颇有觉悟。
扁平数据结构转Tree、树形结构扁平化 都是平时常用的算法。一直没有认真的整理下,特写此文以作整理、记录。
算法的一些东西上文也科普的很好,不做累赘的重复了,有意可以去上文了解了解。
以下是在上文实现的基础上调整过的版本:
去除了根id = 0 的设定,使得兼容性更好: 不存在父节点的项都作为根节点。
新增了 idKey
、pidKey
、childKey
参数,以获得更好的适用性,能根据数据实际情况传入对应的id、父id、children。
整理下算法思路:
- 根据源数据的
id
生成Map
- 遍历源数据
Map
中存在以pid
为键的对象(Map[pid]
),则当前项为Map[pid]
的子元素,保存到Map[pid].children
Map
中不存在以pid
为键的对象,则当前项为根元素,保存到结果集中
- 返回结果集
以下完整代码:
// 测试数据
let arr = [
{ id: 1, name: '部门1', pid: 0 },
{ id: 2, name: '部门2', pid: 1 },
{ id: 3, name: '部门3', pid: 1 },
{ id: 4, name: '部门4', pid: 3 },
{ id: 5, name: '部门5', pid: 4 },
]
// 测试数据二(来自上文评论)
var arr1 = [
{ "id": 7, "pid": 4, "text": "F[父C]" },
{ "id": 6, "pid": 30, "text": "B" },
{ "id": 5, "pid": 6, "text": "D[父B]" },
{ "id": 4, "pid": 1, "text": "C[父A]" },
{ "id": 3, "pid": 7, "text": "G[父F]" },
{ "id": 2, "pid": 4, "text": "E[父C]" },
{ "id": 1, "pid": 20, "text": "A" }
]
function arrayToTree(items, idKey = 'id', pidKey = 'pid', childKey = 'children') {
const result = []; // 存放结果集
const itemMap = {}; //
for(const item of items){
itemMap[item[idKey]] = { ...item, [childKey]: []}
}
for (const item of items) {
const id = item[idKey];
const pid = item[pidKey];
const treeItem = itemMap[id];
if (!itemMap[treeItem.pid]) {
result.push(treeItem)
} else {
itemMap[pid][childKey].push(treeItem)
}
}
return result;
}
首发掘金。