【刷题】Map格式转变为树状格式(简单)

2024-07-09 08:30:02 浏览数 (1)

需求

假设有一个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

代码语言:javascript复制
const rootChildren = data.map((item) => {
    // 解构赋值
    const [parentLabel, childrenLabels] = item
    ...
  })

然后我们创建根节点

代码语言:javascript复制
    // 创建父节点
    const parentNode = {
      id: parentIdCounter  ,
      label: parentLabel,
      children:[]
    }

递归创建叶子节点,也就是给根节点的children属性赋值

代码语言:javascript复制
    // 递归创建子节点
  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)

0 人点赞