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

news/2024/5/20 2:32:59 标签: 前端, 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.niftyadmin.cn/n/5132542.html

相关文章

k8s安装时初始化报错:error execution phase preflight

服务器配置与k8s版本 系统版本&#xff1a; CentOS Linux release 7.9.2009 (Core)内核版本&#xff1a; [rootk8s-node02 tmp]# uname -r 5.4.259-1.el7.elrepo.x86_64k8s版本 v1.15.1 [rootk8s-node1 tmp]# kubeadm version kubeadm version: &version.Info{Major:&q…

[算法]求n!在m进制下末尾有多少个0

参考链接&#xff1a;求n&#xff01;在m进制下末尾0的个数_.!零n,,m-CSDN博客 我们这里和参考链接不同 使用结构体去存储每个因数的信息 然后使用变量index作为索引&#xff0c;其最终值为因数的个数 具体原理&#xff1a; 例子1&#xff1a;求9&#xff01;在10进制下的…

bbr 流相互作用图示

类似 AIMD 收敛图&#xff0c;给出 bbr 的对应图示&#xff1a; bbr 多流相互作用非常复杂&#xff0c;和右下角的 AIMD 相比&#xff0c;毫无美感&#xff0c;但是看一眼左下角的 bbr 单流情况&#xff0c;又过于简陋&#xff0c;而 bbr 的核心就基于这简陋的假设。 浙江温…

c语言基础:L1-061 新胖子公式

根据钱江晚报官方微博的报导&#xff0c;最新的肥胖计算方法为&#xff1a;体重(kg) / 身高(m) 的平方。如果超过 25&#xff0c;你就是胖子。于是本题就请你编写程序自动判断一个人到底算不算胖子。 输入格式&#xff1a; 输入在一行中给出两个正数&#xff0c;依次为一个人的…

Element 多个Form表单 同时验证

一、背景 在一个页面中需要实现两个Form表单&#xff0c;并在页面提交时需要对两个Form表单进行校验&#xff0c;两个表单都校验成功时才能提交 所用技术栈&#xff1a;Vue2Element UI 二、实现效果 三、多个表单验证 注意项&#xff1a; 两个form表单&#xff0c;每个表单上…

拉扎维模拟CMOS集成电路设计西交张鸿老师课程P2~5视频学习记录

目录 p2 p3 p4 p5 --------------------------------------------------------------------------------------------------------------------------------- p2 -----------------------------------------------------------------------------------------------------…

【教3妹学编程-java实战5】结构体字段赋值的几种方式

插&#xff1a; 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站。 坚持不懈&#xff0c;越努力越幸运&#xff0c;大家一起学习鸭~~~ 2哥 :3妹&#xff0c;考考你&#xff0c;你知道java结…

Java面向对象(进阶)-- 拼电商客户管理系统(康师傅)

文章目录 一、目标二、需求说明&#xff08;1&#xff09;主菜单&#xff08;2&#xff09;添加客户&#xff08;3&#xff09;修改客户&#xff08;4&#xff09;删除客户&#xff08;5&#xff09;客户列表 三、软件设计结构四、类的设计&#xff08;1&#xff09;Customer类…