对于一些树形组件中有时候需要对数据进行一个树形存储的转化,今天来介绍两种方式,
第一种: 数组循环,通俗易懂
第二种:递归,代码简单,但是需要理解
首先,我们来定义一个变量
const data = [
{ id: 56, parentId: 62, text: '文本1' },
{ id: 81, parentId: 80, text: '文本2' },
{ id: 74, parentId: null, text: '文本3' },
{ id: 76, parentId: 80, text: '文本4' },
{ id: 63, parentId: 62, text: '文本5' },
{ id: 80, parentId: 86, text: '文本6' },
{ id: 87, parentId: 86, text: '文本7' },
{ id: 62, parentId: 74, text: '文本8' },
{ id: 86, parentId: 74, text: '文本9' },
];
第一种:数组的方式
思路:
一、建立一个映射表,给每一个对象加上对应的索引,以便于在数组中快速定位到该对象
二、通过foreach循环来判断,进而增加对应的子元素
废话不说,上代码
// 建立映射关系
const idMapping = data.reduce((acc, el, i) => {
acc[el.id] = i;
return acc;
}, {});
let root;
data.forEach(el => {
// 判断根节点
if (el.parentId === null) {
root = el;
return;
}
// 用映射表找到父元素
const parentEl = data[idMapping[el.parentId]];
// 把当前元素添加到父元素的`children`数组中
parentEl.children = [...(parentEl.children || []), el];
});
console.log(root);
效果图
第二种:递归(强烈推荐)
思路:封装一个函数,利用先序遍历的方式,逐层调用自身,进行遍历
// 顺序表数据转换为树形存储
function tranListToTreeData(depts, header) {
const arr = []
depts.forEach(item => {
if (item.parentId === header) {
const children = tranListToTreeData(depts, item.id)
if (children.length) {
item.children = children
}
arr.push(item)
}
})
return arr
}
console.log(tranListToTreeData(data, null));
效果图
一毛一样,有没有?代码少写了多少行?
个人总结,错误的地方,希望各位大佬指出,或者更好的方法,评论区留言,给大伙磕一个