需求
假设有一个map,数据结构如下
代码语言:javascript复制{
哈尔滨: ['哈尔滨1', '哈尔滨2'],
天津: ['天津1', '天津2'],
}
想把它转变为树状格式,该如何做:
代码语言:javascript复制[
{
"id": 1,
"label": "哈尔滨",
"children": [
{
"id": 3,
"label": "哈尔滨1"
},
{
"id": 4,
"label": "哈尔滨2"
}
]
},
{
"id": 2,
"label": "天津",
"children": [
{
"id": 5,
"label": "天津1"
},
{
"id": 6,
"label": "天津2"
}
]
}
]
思路
我们可以看到,map的键名是根节点,键值是叶子节点。 要对map进行操作,可以先把它转变为我们常用的数组形式 所以第一步可以把map转变为二维数组
代码语言:javascript复制const buildTree = (item) => {
// map转为二维数组
const data = Object.entries(item)
return convertToTree(data)
}
这样子每一项都是一个二维数组,第一项是键名,第二项以数组的形式表示键值。 如下,其中一项
代码语言:javascript复制[
"哈尔滨",
[
"哈尔滨1",
"哈尔滨2"
]
]
我们对这个数组进行操作,首先对其解构,第一项赋值给parentLabel
,第二项赋值给childrenLabels
const rootChildren = data.map((item) => {
// 解构赋值
const [parentLabel, childrenLabels] = item
...
})
然后我们创建根节点
代码语言:javascript复制 // 创建父节点
const parentNode = {
id: parentIdCounter ,
label: parentLabel,
children:[]
}
递归创建叶子节点,也就是给根节点的children
属性赋值
// 递归创建子节点
if (childrenLabels.length) {
parentNode.children = childrenLabels.map((childLabel) => {
return {
id: childIdCounter ,
label: childLabel,
}
})
}
代码
代码语言:javascript复制const myMap = {
哈尔滨: ['哈尔滨1', '哈尔滨2'],
天津: ['天津1', '天津2'],
}
// map的长度
const childLength = Object.keys(myMap).length 1
// id计数器(自增)
let parentIdCounter = 1 // 父节点id计数器
let childIdCounter = childLength // 子节点id计数器(从开始
/* 二维数组转换成树:即第二层数组转变为相应形式的对象格式
二维数组实例:
[
"哈尔滨",
[
"哈尔滨1",
"哈尔滨2"
]
] */
const convertToTree = (data) => {
const rootChildren = data.map((item) => {
// 解构赋值
const [parentLabel, childrenLabels] = item
// 创建父节点
const parentNode = {
id: parentIdCounter ,
label: parentLabel,
children: [],
}
// 递归创建子节点
if (childrenLabels.length) {
parentNode.children = childrenLabels.map((childLabel) => {
return {
id: childIdCounter ,
label: childLabel,
}
})
}
// 返回父节点
return parentNode
})
// 假设所有父节点都是根节点的子节点
return rootChildren
}
/**
* map转化为二层树
*/
const buildTree = (item) => {
// map转为二维数组
const data = Object.entries(item)
return convertToTree(data)
}
const tree = buildTree(myMap)
console.log(tree)