需求
源数据
let srcList = ['动物-昆虫-蚂蚁', '动物-昆虫', '植物-草-绿色', '植物-花-红色','植物-花-黄色']
- 去重分类
- 构建树形数据如下
[
{
"name": "动物",
"children": [
{
"name": "昆虫",
"children": [
{
"name": "蚂蚁"
}
]
}
]
},
{
"name": "植物",
"children": [
{
"name": "草",
"children": [
{
"name": "绿色"
}
]
},
{
"name": "花",
"children": [
{
"name": "红色"
},
{
"name": "黄色"
}
]
}
]
}
]
思路
- 避免多根将每一条分类信息路径,视为容器数组内的元素
- 使用固定指针记录目标根位置,游标指针匹配节点,移动
- 新增节点之前判断是否有同名节点存在,存在则进入其下层子节点
- 进入新增节点域,须判断当前节点是否为叶子节点,是则裁剪该子节点指向
- 每轮路径信息匹配,需重置游标指针于根位置
解法
function listToTree(srcList) {
// 1.记录根位置
let destList = []
srcList.forEach(path => {
// 2.待匹配项
let pathList = path.split('-')
// 3.将移动指针重置顶层,确保每次从根检索匹配(必须!!!)
let levelList = destList
// 4.遍历待询节点
for (let name of pathList) {
// 5.同层同名节点查找匹配
let obj = levelList.find(item => item.name == name)
// 6.若不存在则建立该节点
if (!obj) {
obj = { name, children: [] }
levelList.push(obj)
// 7.若当前被增节点是叶子节点,则裁剪该节点子节点属性
if (name == pathList[pathList.length - 1]) {
delete obj.children
}
}
// 8.已有则进入下一层,继续寻找
levelList = obj.children
}
})
return destList
}
测试
let srcList = ['动物-昆虫-蚂蚁', '动物-昆虫', '植物-草-绿色', '植物-花-红色','植物-花-黄色']
let result = listToTree(srcList)
console.log(JSON.stringify(result, null, 2))