今天开始记录一些自己经常遇到的数据处理技巧和项目思路,跨度时间长的项目后来都忘记自己做过什么或者怎么做的了,以备不时之需✊
前言
现在前端页面中数据驱动视图为主,我们经常会碰到请求返回的数据仅仅是一个扁平的数组,而我们渲染结构的时候发现直接渲染是行不通,就需要一些小小的算法了。
扁平数组转Tree
假设后端返回的数组是这个平铺的部门数组
const data = [
{id:"01", name: "张大大", pid:"", job: "项目经理"},
{id:"02", name: "小亮", pid:"01", job: "产品leader"},
{id:"07", name: "小丽", pid:"02", job: "产品经理"},
{id:"08", name: "大光", pid:"02", job: "产品经理"},
{id:"03", name: "小美", pid:"01", job: "UIleader"},
{id:"09", name: "小高", pid:"03", job: "UI设计师"},
{id:"04", name: "老马", pid:"01", job: "技术leader"},
{id:"05", name: "老王", pid:"01", job: "测试leader"},
{id:"06", name: "老李", pid:"01", job: "运维leader"},
{id:"10", name: "小刘", pid:"04", job: "前端工程师"},
{id:"11", name: "小华", pid:"04", job: "后端工程师"},
{id:"12", name: "小李", pid:"04", job: "后端工程师"},
{id:"13", name: "小赵", pid:"05", job: "测试工程师"},
{id:"14", name: "小强", pid:"05", job: "测试工程师"},
{id:"15", name: "小涛", pid:"06", job: "运维工程师"}
]
首先我们分析,这样一个数组是有特点的,部门老大的id和每个成员的pid相同,我们期望生成的数组结构如下:
[{ label: '张大大', children: [ { label: '小亮', children: [{label: '小丽'},{label: '大光'}]
},
{
label: '小美',
children: [{label: '小高'}]
},
{
label: '老马',
children: [{label: '小刘'},{label: '小华'},{label: '小李'}]
},
{
label: '老王',
children: [{label: '小赵'},{label: '小强'}]
},
{
label: '老李',
children: [{label: '小涛'}]
}
]
}]
方式一:filter,直接上代码了
function tranData2Tree(data) {
const treeData = []
data.forEach(item => {
if (!item.pid) { // 此处可短路运算加上 || item.pid === 顶级的pid
treeData.push(item) // obj.pid === false 找顶级
}
// 筛选出当前obj id 与其他obj pid相等的对象
const resArr = data.filter(data => item.id === data.pid)
if (!resArr.length) return
// 给每一个对象添加子数组
item.children = resArr
})
return treeData
}
方式二:递归
function tranData2Tree(data, rootValue) { // rootValue为顶级节点的pid,此处传''即可
const treeData = []
data.forEach(item => {
if (item.pid === rootValue) { // 判断每一项的pid和根项的id是否相同
// 递归调用找到子项,子项存在添加
const children = tranData2Tree(data, item.id)
if (children.length) {
item.children = children
}
treeData.push(item)
}
})
return treeData
}
结语
没有考虑性能方面的问题,写的不好,有错误的地方烦请各位大佬多多指教,感恩家人感恩🙏
🚩祝各位一路顺风,顶峰相见