//例
//层数不定 每一层数据条数不定
let arr = [
{id: 1, parentId: ''},
{id: 2, parentId: 1},
{id: 3, parentId: 2}
]
//需要转化成
newArr = [
{
id: 1,
parentId: '',
children: [
{
id: 2,
parentId: 1,
children: [
{
id: 3,
parentId: 2
}
]
}
]
}
]
//代码实现
//法一
//parentId默认值为''
function translateDataToTree(data, parentId = '') {
let tree = [];
let temp;
data.forEach((item, index) => {
if (data[index].parentId == parentId) {
let obj = data[index];
temp = translateDataToTree(data, data[index].id);
if (temp.length > 0) {
obj.children = temp;
}
tree.push(obj);
}
})
return tree;
}
//法二
function translateDataToTree(array) {
//第一层数据
let parents = array.filter(item => item.parentId === "");
//有父节点的数据
let childrens = array.filter(item => item.parentId !== "");
function translator(parents, childrens) {
parents.forEach( parent => {
childrens.forEach( (children, index) => {
//找到子层的父层
if (children.parentId === parent.id) {
//temp 这步不是必须
//对子节点数据进行深复制
let temp = JSON.parse(JSON.stringify(childrens));
//让当前子节点从temp中移除,temp作为新的子节点数据,这里是为了让递归时,子节点的遍历次数更少,如果父子关系的层级越多,越有利
temp.splice(index, 1);
//判断是否有children属性 有就直接push 没有就增加children属性
parent.children ? parent.children.push(children) : parent.children = [children];
//不用temp 传childrens也可
translator([children], temp);
}
})
})
}
translator(parents, childrens);
//返回最终结果
return parents;
}
最主要的是递归的使用
第二种方式使用map
function arrayToTree(arr) {
const idMap = new Map()
const result = []
// 初始化 Map
arr.forEach((item) => {
idMap.set(item.id, { ...item, children: [] })
})
// 构建树
arr.forEach((item) => {
const parent = idMap.get(item.parentId)
if (parent) {
parent.children.push(idMap.get(item.id))
} else {
result.push(idMap.get(item.id))
}
})
return result
}