数组转换为树形结构
let menu = [
{ id: 1, name: '菜单1', parentId: 0 },
{ id: 2, name: '菜单2', parentId: 0 },
{ id: 3, name: '菜单1-1', parentId: 1 },
{ id: 4, name: '菜单1-2', parentId: 1 },
{ id: 5, name: '菜单1-1-1', parentId: 3 },
{ id: 6, name: '菜单2-1', parentId: 2 },
{ id: 7, name: '菜单1-1-1-1', parentId: 5 },
];
function transformTree(data) {
let res = [];
//使用map保存将当前对象
let map = {};
for (let v of data) {
map[v.id] = v;
}
for (let v of data) {
//查找当前节点是否存在父节点
let parent = map[v.parentId];
if (parent) {
//若为第一次,将父节点的children初始化为空数组用于保存子节点
if (!parent.children) parent.children = [];
parent.children.push(v);
} else {
//若无父节点直接添加到res中
res.push(v);
}
}
return res;
}
console.log(transformTree(menu));
转化为:
let menu2= [
{
id: 1,
name: '菜单1',
parentId: 0,
children: [
{
id: 3,
name: '菜单1-1',
parentId: 1,
children: [
{
id: 5,
name: '菜单1-1-1',
parentId: 3,
children: [{ id: 7, name: '菜单1-1-1-1', parentId: 5 }],
},
],
},
{ id: 4, name: '菜单1-2', parentId: 1 },
],
},
{
id: 2,
name: '菜单2',
parentId: 0,
children: [{ id: 6, name: '菜单2-1', parentId: 2 }],
},
];
树形结构转换为数组结构
//广度优先
function transformArr(data) {
let queue = data;
let res = [];
//当队列为空时就跳出循环
while (queue.length != 0) {
let item = queue.shift();
res.push({
id: item.id,
parentId: item.parentId,
name: item.name,
});
let child = item.children;
if (child) {
for (let v of child) {
queue.push(v); //将子节点加入到队列尾部
}
}
}
return res;
}
console.log(transformArr(menu2))
PS:对树形结构进行增删改查时,可以先将树形结构转换成数组操作完后再转换成树形结构即可
多级菜单查找某一子菜单并返回相应节点
//深度优先
function findData(tree, target) {
let res = {};
for (let val of tree) {
deep(val, target);
//找到就返回
if (JSON.stringify(res) !== '{}') return res;
}
function deep(val, target) {
if (val.name === target) {
res = val;
} else {
if (val.children) {
for (let v of val.children) {
deep(v, target);
}
}
}
}
}
console.log(findData(menu2, '菜单1-1-1'));