JS数组转树

297 阅读1分钟

数组转树

题目

定义一个 convert 函数,将以下数组转换为树结构。

const arr = [
    { id: 1, name: '部门A', parentId: 0 }, // 0 代表顶级节点,无父节点
    { id: 2, name: '部门B', parentId: 1 },
    { id: 3, name: '部门C', parentId: 1 },
    { id: 4, name: '部门D', parentId: 2 },
    { id: 5, name: '部门E', parentId: 2 },
    { id: 6, name: '部门F', parentId: 3 },
]

分析

定义树节点的数据结构

interface ITreeNode {
    id: number
    name: string
    children?: ITreeNode[]
}

遍历数组,针对每个元素

  • 生成 tree node
  • 找到 parentNode 并加入到它的 children

找 parentNode 时,需要根据 id尽快找到 tree node
需要一个 map ,这样时间复杂度是 O(1) 。否则就需要遍历查找,时间复杂度高。

实现

/**
 * 生成树形结构数据
 * @param {Object} data
 * @param {String} field 区分自身的key, example: 'id'
 * @param {String} parentField 表示父节点的key, example: 'parentId'
 * @param {String} title 用于显示名称的字段
 * @return {Array}
 */
export function genTreeData(data, field, parentField, title) {
  data.forEach((item) => { delete item.children })

  const map = {}
  data.forEach((item) => { map[item[field]] = item })

  const val = []
  data.forEach((item) => {
    const parent = map[item[parentField]]
    item.id = item[field]
    item.label = item[title]
    if (parent) {
      (parent.children || (parent.children = [])).push(item)
    } else {
      val.push(item)
    }
  })
  return val
}

扩展

这两种数据结构很像 MySQL vs Mongodb ,一个关系型,一个文档型