当前位置: 首页 > article >正文

前端小技巧: TS实现数组转树,树转数组

将数组转为树

interface IArrayItem {
  id: number,
  name: string,
  parentId: number
}

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

const arr = [
  {id: 1, name: '部门A', parentId: 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}
]

function convert(arr: IArrayItem[]): ITreeItem | null {
  // 用于id和treeNode的映射关系表
  const idToTreeNode: Map<number, ITreeNode> = new Map()
  let root = null
  arr.forEach(item => {
    const {id, name, parentId} = item
    const treeNode: ITreeNode = { id, name }
    idToTreeNode.set(id, treeNode)
    // 找到 parentNode 并加入到它的 children
    const parentNode = idToTreeNode.get(parentId)
    if (parentNode) {
      !parentNode.children && parentNode.children = [] // 没有则初始化一个
      parentNode.children.push(treeNode)
    }
    // 找到根节点
    if (!parentId) root = treeNode
  })
  return root
}

const tree = convert(arr)
console.log('tree: ', tree)
  • 遍历数组,生成 tree node

  • 找到parentNode,加入其children

  • 扩展:

    • 数组:像是mysql, 关系型
    • 树,像是文档型

将树转数组

const obj = {
  id: 1,
  name: '部门a',
  children: [
    {
      id: 2,
      name: '部门b',
      children: [
        { id: 4, name: '部门d'}
        { id: 5, name: '部门e'}
      ]
    },
    {
      id: 3,
      name: '部门c',
      children: [
        { id: 6, name: '部门f'}
      ]
    }
  ]
}

interface IArrayItem {
  id: number,
  name: string,
  parentId: number
}

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

const arr = []

// 使用广度优先遍历,最好

function convert(root: ITreeNode): IArrayItem[] {
  const nodeToParent: Map<ITreeNode, ITreeNode> = new Map()
  const arr: IArrayItem[] = []
  const queue = ITreeNode[] = []
  queue.unshift(root) // 根节点入队

  while(queue.length) {
    const curNode = queue.pop() // 出队
    if (!curNode) break
    const { id, name, children = [] } = curNode

    // 创建数组 item 并 push
    const parentNode = nodeToParent.get(curNode)
    const parentId = parentNode?.id || 0
    const item = { id, name, parentId }
    arr.push(item) // 只在这里加入

    // 子节点入队
    children.forEach(child => {
      // 映射 parent
      nodeToParent.set(child, curNode)
      // 入队
      queue.unshift(child)
    })
  }
}

const arr = convert(obj)
console.log('arr:', arr)

http://www.kler.cn/a/108227.html

相关文章:

  • 如何提高自动驾驶中惯性和卫星组合导航pbox的精度?
  • 【MySQL从入门到放弃】InnoDB磁盘结构(一)
  • 华为数通HCIA系列第5次考试-【2024-46周-周一】
  • 云原生-docker安装与基础操作
  • 在C++上实现反射用法
  • SCUI Admin + Laravel 整合
  • LeetCode--196. 删除重复的电子邮箱
  • C++ 笔记
  • 深入了解 Elasticsearch 8.1 中的 Script 使用
  • 【swagger动态配置输入参数忽略某些字段】
  • 如何确定Apache Kafka的大小和规模
  • Azure - 自动化机器学习AutoML Azure使用详解
  • ruoyi vue前后端分离功能介绍
  • 基于 Redis + Lua 脚本实现分布式锁,确保操作的原子性
  • Web APIs——事件流
  • 【CSDN 每日一练 ★★☆】【字符串】外观数列
  • golang连接池检查连接失败时如何重试
  • Linux网络编程01
  • npm更新包时This operation requires a one-time password.
  • 数学家陶哲轩在形式证明帮助下发现论文中错误
  • moviepy处理手机端图片旋转问题
  • JAVA同城服务智慧养老小程序怎么开发?
  • 企业微信接入芋道SpringBoot项目
  • sql--索引使用
  • sharepoint2016-2019升级到sharepoint订阅版
  • python DevOps