1. 扁平化数据 ---- > 树形结构
1.1 第一种数据类型
let data = [
{ id: 639, name: "商品管理", type: 0, pId: 638, code: "1", domain: "" },
{ id: 640, name: "商品分类", type: 0, pId: 639, code: "2", domain: "" },
{ id: 642, name: "增加分类", type: 0, pId: 640, code: "3", domain: "" },
{ id: 645, name: "编辑分类", type: 0, pId: 640, code: "4", domain: "" },
{ id: 646, name: "消息管理", type: 0, pId: 655, code: "4", domain: "" },
]
- 第一种方法,网上找的
function toTree(data) {
const map = {}
const val = []
data.forEach((item) => {
map[item.id] = item
})
data.forEach((item) => {
const parent = map[item.pId]
if (parent) {
(parent.children || (parent.children = [])).push(item)
} else {
val.push(item)
}
})
return val
},
- 自己写的比较奇葩
/*
两层循环找出id和pId相同的放入到外层循环的children中
但是此时要删除那些已经放入到children中的列表项,并删除那些children为空的属性
才能得到最后的结果
*/
function toTree1(data){
let del = []
data.forEach(el => {
el.children = []
data.forEach((item) => {
if (item.pId == el.id) {
el.children.push(item)
del.push(item.id)// 删除那些要推进列表中的即可这些是重复的item删除
}
})
// 删除那些children为空的数据
if(el['children'].length == 0){
delete el['children']
}
})
// 过滤那些已经push到el.children中的
let result= data.filter(item=>!del.includes(item.id))
return result
}
使用:
console.log(toTree(data), '第一种方法');
console.log(toTree1(data), '第二种方法');
结果:
-
tips
: 这种方法对于那种parentId==0
的也是可以的。把代码中的pId
改为parnetId
即可。
2. 树形结构---->扁平化数据
我可写出了个递归……哭。刚开始可以先写两层转换、看看思路对不,最后再抽取那些重复的代码封装成函数递归。
function flattTree(data){
let res=[]//保存最后的数据
data.forEach(el=>{
if(el.children){
res.push(el)//当前父亲肯定要push到res里面的 是要把孩子删除了吗再
//第二层循环,发现这是重复的地方,使用递归了在这个点
el.children.forEach(item=>{
if(item.children){
res.push(item)
}else{
res.push(el.children)
}
})
}else{
res.push(el)
}
})
console.log(res,'未使用递归的时候的粗糙的代码');
}
let treeData=toTree(data)//树形结构原始数据
flattTree(treeData)
let treeData=toTree(data)//原始数据结构
let res=[]
flattTree(treeData,res)
console.log(res,'扁平化的数据');
function flattTree(data,res){
data.forEach(el=>{
if(el.children){
res.push(el)
flattTree(el.children,res)//递归
//要把孩子children删除掉
delete el['children']
}else{
res.push(el)
}
})
}