js扁平结构转树状结构

扁平数据结构转换为树状结构

/**
 * @description 扁平数据转树状
 * @param {Array} arr 扁平数据
 * @param {String} id id字段名
 * @param {String} pid 父id字段名
 * @returns {Array} tree 树状结构
*/
function arrayToTree(arr, id, pid) {
  let tree = []
  const lv1 = getLv1(arr) // 1. 先将一级菜单获取到,放到一个数组里边
  tree = addSon(lv1)
  function addSon (lv1) {
    arr.forEach((item) => {
      if(!item.children) item.children = [] // 给所有菜单加上children节点
      // console.log('执行了');
      if (item[pid]) {
        lv1.forEach((lv1Item) => {
          if (item[pid] === lv1Item[id]) {
            if(!lv1Item.children) lv1Item.children = []
            lv1Item.children.push(item)
            const newarr = []
            newarr.push(item)
            return addSon(newarr)
          }
        })
      }
    })
    return lv1
  }
  function getLv1 (arr) {
    const lv1 = []
    arr.forEach((item) => {
      if (item[pid] === 0) {
        lv1.push(item)
      }
    })
    return lv1
  }
  return tree
}
/**
 * @description 扁平数据转树状
 * @param {Array} arr 扁平数据
 * @param {String} id id字段名
 * @param {String} pid 父id字段名
 * @returns {Array} tree 树状结构
*/
function arrayToTree(arr = [], id = 'id', pid = 'pid') {
    const data = JSON.parse(JSON.stringify(arr))
    const idMap = new Map()
    const tree = []
    // 转换为id映射
    data.forEach(item => idMap.set(item[id], item))
    // 遍历数据,找到根节点, 并追加children节点
    data.forEach(item => {
        if (!item[pid]) return tree.push(item)
        const parent = idMap.get(item[pid])
        if (!parent.children) parent.children = []
        parent.children.push(item)
    })
    return tree
}

数据测试

const arr = [
  { id: 1, label: '系统管理', pid: 0 },
  { id: 2, label: '用户管理', pid: 1 },
  { id: 3, label: '角色管理', pid: 1 },
  { id: 4, label: '菜单管理', pid: 1 },
  { id: 5, label: '视频管理', pid: 0 },
  { id: 6, label: '视频分类', pid: 5 },
  { id: 7, label: '视频标签', pid: 5 },
  { id: 8, label: '视频标签-add', pid: 7 },
  { id: 9, label: '视频标签-del', pid: 7 },
]

// 递归方式
console.log(arrayToTree(arr, 'id', 'pid'))
// id映射引用方式
console.log(arrayToTree(arr))

测试输出

[
  {
    id: 1,
    label: '系统管理',
    pid: 0,
    children: [
      { id: 2, label: '用户管理', pid: 1 },
      { id: 3, label: '角色管理', pid: 1 },
      { id: 4, label: '菜单管理', pid: 1 },
    ],
  },
  {
    id: 5,
    label: '视频管理',
    pid: 0,
    children: [
      { id: 6, label: '视频分类', pid: 5 },
      {
        id: 7,
        label: '视频标签',
        pid: 5,
        children: [
          { id: 8, label: '视频标签-add', pid: 7 },
          { id: 9, label: '视频标签-del', pid: 7 },
        ],
      },
    ],
  }
]
© 版权声明
THE END
喜欢就支持一下吧
点赞5 分享
评论 共2条

请登录后发表评论