需求
假设有一个map,数据结构如下
{哈尔滨: ['哈尔滨1', '哈尔滨2'],天津: ['天津1', '天津2'],
}
想把它转变为树状格式,该如何做:
[{"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转变为二维数组
const buildTree = (item) => {// map转为二维数组const data = Object.entries(item)return convertToTree(data)
}
这样子每一项都是一个二维数组,第一项是键名,第二项以数组的形式表示键值。
如下,其中一项
["哈尔滨",["哈尔滨1","哈尔滨2"]
]
我们对这个数组进行操作,首先对其解构,第一项赋值给parentLabel
,第二项赋值给childrenLabels
const rootChildren = data.map((item) => {// 解构赋值const [parentLabel, childrenLabels] = item...})
然后我们创建根节点
// 创建父节点const parentNode = {id: parentIdCounter++,label: parentLabel,children:[]}
递归创建叶子节点,也就是给根节点的children
属性赋值
// 递归创建子节点if (childrenLabels.length) {parentNode.children = childrenLabels.map((childLabel) => {return {id: childIdCounter++,label: childLabel,}})}
代码
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)