数组转化成树(难点-难点-难点)
data =
[
{id:"01", name: "张大大", pid:"", job: "项目经理"},
{id:"02", name: "小亮", pid:"01", job: "产品leader"},
{id:"03", name: "小美", pid:"01", job: "UIleader"},
{id:"04", name: "老马", pid:"01", job: "技术leader"},
{id:"05", name: "老王", pid:"01", job: "测试leader"},
{id:"06", name: "老李", pid:"01", job: "运维leader"},
{id:"07", name: "小丽", pid:"02", job: "产品经理"},
{id:"08", name: "大光", pid:"02", job: "产品经理"},
{id:"09", name: "小高", pid:"03", job: "UI设计师"},
{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: "运维工程师"}
]
目标:
const treeData = arrToTree(data)
treeData就是:
[{ label: '张大大', children: [ { label: '小亮', children: [{label: '小丽'},{label: '大光'}]
},
{
label: '小美',
children: [{label: '小高'}]
},
{
label: '老马',
children: [{label: '小刘'},{label: '小华'},{label: '小李'}]
},
{
label: '老王',
children: [{label: '小赵'},{label: '小强'}]
},
{
label: '老李',
children: [{label: '小涛'}]
}
]
}]
//总方法
function arrToTree(data) {
let arr = []
data.forEach(item => {
if (!item.pid) {
// 如果id为空,则放在根节点下
arr.push({
label: item.name,
id: item.id
})
} else {
// 如果id不为空,则执行【对象插入树算法】
buildTree(arr, item)
}
})
// 执行【清除id算法】以清除构建数据过程中临时创建的id属性,并返回数据
return removeId(arr)
}
// 【对象插入树算法】
function buildTree(arr, obj) {
arr.forEach(item => {
if (obj.pid === item.id) {
// 先比较item是否是obj的上级
if (!item.children) {
item.children = []
}
item.children.push({
label: obj.name,
id: obj.id
})
} else if (item.children) {
// 如果item不是obj的上级,且item有孩子,那查看孩子是不是obj的上级(递归)
buildTree(item.children, obj)
}
})
}
// 【清除id算法】
function removeId(arr) {
arr.forEach(item => {
// 删除item的id
delete item.id
if (item.children) {
// 如果item有孩子,删除item孩子的id(递归)
removeId(item.children)
}
})
return arr
}
//打印查看结果
console.log(arrToTree(data))
/**
* 把平铺的数组结构转成树形结构
*
* [
* {id:"01", pid:"", "name":"老王" },
* {id:"02", pid:"01", "name":"小张" }
* ]
* 上面的结构说明: 老王是小张的上级
*/
export function tranListToTreeData(item) {
// 最重要产出的数据结构
const newList = []
// 把item的每一项都用对象存储起来,因为要给每一项增加一个id指向 方便之后往里头添加东西,先把空盒子搭起来21行填东西
const everyitem = {}
// 建立映射关系,通过id快速找到对应的元素
item.forEach(element => {
if (!element.children) {
element.children = []
}
//
everyitem[element.id] = element
// "312c": { 'id': '312c', 'pid': '', 'name': '财务部', children: [{ 'id': '312d', 'pid': '312c', 'name': '财务核算部',children: []}] },
// "312d": { 'id': '312d', 'pid': '312c', 'name': '财务核算部',children: []}
// }
element.forEach(ite => {
// 现在对于每一个元素来说 先找到他的上级 如果能找到 说明有上级 并把它添加到上级的children中 如果找不到 说明他没有上级 直接添加到 最终的数据结构中
const parent = everyitem[ite.pid]
if (parent) {
parent.children.push(ite)
} else {
newList.push(ite)
}
})
return newList
})
}
// 两个小练习
将
`[ { label: '男', value: 0 }, { label: '女', value: 1 } ]`
转换成
`{0: '男', 1:'女'}`
const arr = [
{ label: '男', value: 0 },
{ label: '女', value: 1 }
]
function f1(arr) {
return arr.reduce((obj, cur) => {
obj[cur.value] = cur.label
return obj
}, {})
}
function f2(arr) {
let obj = {}
arr.forEach(item => {
obj[item.value] = item.label
})
return obj
}
const obj1 = f1(arr) // obj ===> {0: '男', 1:'女'}
const obj2 = f2(arr) // obj ===> {0: '男', 1:'女'}
console.log(obj1)
console.log(obj2)
将
`{ 0: '男', 1:'女'}`
转换成
`[{label: '男', value: 0},{label: '女', value: 1}]`
const obj = { 0: '男', 1:'女'}
function f(obj) {
let arr = []
for (const key in obj) {
arr.push({
label: obj[key],
value: key
})
}
return arr
}
const arr = f(obj) // arr ===> [{label: '男', value: 0},{label: '女', value: 1}]
console.log(arr)