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

JavaScript生存指南:DOM操作、事件循环与真实工程陷阱 JavaScript 是一种运行在浏览器中的动态、单线程、事件驱动的脚本语言,其核心机制围绕执行上下文、原型链、隐式类型转换和事件循环展开。理解 `==` 与 `===` 的差异、`[] == ![]` 的转换逻辑,本质是掌握 JS 运行时类型 coercion 协议;而 `DOMContentLoaded` 与 `load` 的区别,则直指 DOM 渲染生命周期的关键分界。这些底层行为深刻影响首屏性能(如 FCP)、表单交互健壮性及跨端兼容性。本文从真实故障案例切入,解析 DOM 操作代价、微任务队列调度 阅读详情

将数组转为树

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)
ts-tree:用打字稿管理树(图) ts树 最小的脚本来实现树(图形)。 import { Node } from '../src/tree' const A = new Node ( ) const B = new Node ( ) const C = new Node ( ) A . append ( B ) C . appendTo ( B ) C . append ( new Node ( ) , new Node ( ) ) A . append ( new Node ( ) ) console . log ( A . toGraphString ( ) ) x─┬─ Node#0 ├─┬─ Node#1 │ └─┬─ Node#2 │ ├─── Node#3 │ └─── Node#4 └─── Node#5 :hundred_points: 经过节点点击测试。 100%的代码覆盖率 npx tap 立即下载

相关推荐

我每天如何使用 ChatGPT

我偶尔会用这个功能作为开始。我本人非常喜欢阅读,让 ChatGPT 来概括所有文章,感觉就像身处于但丁描述的地狱的某个层次那样痛苦。然而,有时一些文章实在是太啰嗦、无聊,或者写得让人不愉快(比如一个无趣记者对一个让人讨厌的人进行的漫无焦点的采访)。我需要获取这些文章中的一些信息,以便保持信息的更新和了解。在晚期资本主义的广告经济下,很多文章只在一个段落里提供新信息,其余都是无聊的填充内容,只是为了展示糟糕的广告,这实在是对人们的时间和生命的一种浪费。我有几次利用 ChatGPT 来。

KevinDai007的博客 3786

JS 如何快速高效的将数组转换成树形结构

JS 如何快速高效的将数组转换成树形结构 const data = [{ id: 1, pid: 0, name: 'body' }, { id: 2, pid: 1, name: 'title' }, { id: 3, pid: 2, name: 'div' }]; 转化为这种: [{ id: 1,

达拉崩巴斑得贝迪卜多比鲁翁_ 4225

MMDetection框架入门教程(完全版)

  网上MMDetection的教程看似有很多,但感觉都不成系统,看完一圈下来还是不知道MMDetection要怎么用。这里还是推荐直接跟着官方教程,结合源码学习MMDetection,相关链接汇总如下: 官方教程 - MMCV 官方教程 - MMDetection 官方教程 - 不得不知的 MMDetection 学习路线(个人经验版) 西安交大课件 - mmdetection教程(使用篇)   本文会介绍如何在MMDetection中从头开始搭建一套属于自己的算法。前几篇博客算是本人学习过...

Sual 10万+

数组结构和树状结构的互转

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <titl

zm_miner的博客 691

体素坐标(voxel_coors)在mmdetection3d中的理解

体素坐标(voxel_coors)在mmdetection3d中的理解

weixin_38362784的博客 4219

【OpenArm|Control】openarm机械臂ROS2仿真控制

openarm_ros2 存储库包含用于 ros2_control 的包集合。 它抽象化了硬件控制,将手臂公开为接收位置、速度和扭矩命令并输出关节状态的接口。 openarm_bringup 包提供了通过包与 ROS2 控制框架集成的启动文件。该软件包提供启动文件和配置,用于启动硬件接口、加载控制器以及将物理臂连接到 ROS2 生态系统。启动后,您可以使用标准 ROS2 控制工具和接口来命令手臂并接收反馈。openarm_bringup bringup 包支持模拟硬件(用于模拟/测试)和通过硬件插件的真实

ai领域探索者,欢迎一起交流,目前从事具身智能行业。 2959

JavaScript 将树形结构转换一维数组(递归)

将树形结构转换为一维数组是一个常见的任务,通常使用递归或迭代的方法来完成。flattenTree 函数递归地遍历树的每个节点,并将节点添加到结果数组中。如果节点具有子节点,它会继续遍历子节点。最终,你将得到一个包含树中所有节点的一维数组。getOneArr 使用了递归方法,它接受一个包含树形结构数据的数组 data,并将其转换为一维数组。将数据结构从多维树状结构变成一维数组,然后删除了原始数据中的子节点,最后输出一个一维数组,其中包含了所有节点的数据,同时删除了子节点属性,使其成为一个扁平的结构。

qq_36437172的博客 3186

Windows 11下WSL2安装CUDA避坑指南:从驱动版本匹配到环境变量配置

本文详细解析了在Windows 11的WSL2中搭建CUDA开发环境的完整流程与核心避坑要点。关键在于理解“驱动在Windows,工具链在Linux”的独特架构,并确保显卡驱动与CUDA Toolkit版本严格匹配。指南涵盖了从驱动验证、WSL-Ubuntu专用仓库安装、环境变量配置到GCC版本冲突、GPU算力不匹配等常见问题的解决方案,帮助开发者高效构建稳定的深度学习与高性能计算环境。

smartcontract5的博客 474

typeScript数组转树。

ts数组转树

renyudouhui的博客 678

【一】PCIe基础知识

Linux PCIe基础知识

他山之石 可以攻玉 4万+

基于51单片机的电子记分牌的设计

基于51单片机的电子记分牌的设计 电子记分牌基于51单片机的电子记分牌的设计摘要1 引言2 总体设计方案2.1 设计思路(1)设计要求(2)设计思路(3)设计方案2.3综合设计方框图(1)硬件设计框图(2)软件设计3 设计原理分析3.1 电源、复位、下载电路的设计(见图1、2、3)3.2 时钟电路的设计3.3 矩阵键盘电路的设计3.4 数码管显示电路设计4程序代码 摘要 本设计为电子记分牌设计,是以STC89C52芯片为核心,辅以必要电路设计进行的。用4位LED七段数码管显示比赛两方的分数(每方分数用2位

行走的皮卡丘 2037

通过递归,实现数组转树

有时候总会有一些后端工程师, 他们将这种需要有结构的数组传成一个平铺的数据, 看着就烦, 先给他一拳, 再来看看有什么解决办法吧

Qiang_7950的博客 558

强化学习在视觉导航中的应用

强化学习在视觉导航中的应用​ ,人工智能,计算机视觉,大模型,AI,强化学习(Reinforcement Learning, RL)是一种通过智能体(Agent)与环境进行交互,以最大化累积奖励为目标的机器学习范式。它不依赖于预定义的规则或大量标注数据,而是让智能体在试错过程中学习最优策略。计算机视觉(Computer Vision)则赋予智能体 “观察” 环境的能力,使其能够从图像或视频中提取有用信息。

不踩坑,不知道坑有多深;不总结,踩过的坑白踩。 22万+

小程序中字符串转数组如何实现

JS 字符串转数组: var words =' likely, likely, likely,economic, economic';     //字符串中间已特殊符号隔开 var words = words.split(",");    //转成数组类似php的explode函数  JS 字符串去重: function unique (array){ retu...

weixin_33857230的博客 5060

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

数组与 List 相互转换:原理、代码及影响分析

在日常的 Java 开发中,经常会遇到需要在数组和 List 之间进行转换的情况。这看似简单的操作,其实蕴含着一些需要注意的细节,特别是在涉及到数据修改时,可能会对原数据结构产生意想不到的影响,而这些细节在面试中经常会被考察。

m0_57836225的博客 1199

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

JavaScript 数组 —— copyWithin()、concat()、from()

1、copyWithin() copyWithin() 方法用于从数组的指定位置拷贝元素到数组的另一个指定位置中。 语法: array.copyWithin(target, start, end) 参数: 参数 描述 target 必需。复制到指定目标索引位置。 start 可选。元素复制的起始位置。 end 可选。停止复制的索引位置 (默认为 array.lengt...

z1324402468的博客 394

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

vue3 ts 动态表单原理

使用,数组转对象 对象转数组。

孔的博客 462

前端面试(一)

最近在考虑换个新的环境,所以先找了家公司面了下试试水,虽然不知道结果,但是把题目记录下来当做一次学习经历吧! 一、html语义化意义,作用,原因,理解: 1.使代码结构更清晰,在没有CSS的情况下也能呈现出代码层次结构 2.方便其他设备解析(如屏幕阅读器、盲人阅读器、移动设备)以意义的方式来渲染网页 3.提升搜索引擎优化(SEO)的效果 4.便于团队开发和维护,语义化更具可读性,代码更好...

南京小龙虾的博客 526

2024Jinger的前端学习内容总结——前端学习路线(超全)

数据结构与算法、HTML、CSS、Javascript基础、高级以及ES6、Vue2&Vue3、React、Node、前端可视化Cesium|Three

警警的博客 1385

arguments转化为数组

每个函数都有arguments属性存放参数,它是类似数组,但不是数组,不能进行数组操作。 有的时候,我们需要arguments进行一些数字操作,可以将其转化为数组: var slice = Array.prototype.slice,   args = slice.apply(arguments); 这样,变量args就成为存放着arguments元素的数组了。  ...

weixin_30532369的博客 104

Vue3+TS高德地图开发:如何有效处理LngLat(NaN, NaN)错误及数据校验

本文针对Vue3+TS开发高德地图时常见的LngLat(NaN, NaN)错误,提供了从根源到实践的完整解决方案。通过定义严格的TypeScript类型、实现健壮的坐标校验与转换函数、利用Composition API封装安全的地图初始化逻辑,构建全链路数据防御体系,确保坐标数据有效,从而彻底避免地图渲染失败。

w7x8y9z的博客 564

JavaScrtipts 使用手册.md

JavaScrtipts 使用手册.md 插件列表 插件列表 数据隐藏 tootik 常用模块函数 JS 判断对象是否相等 说明: 检查对象"值相等"是一个强大复杂的方法 需要依赖完善的测试库,包含各种边界类型情况. Underscore 和 Lo-Dash 有一个名为_.isEqual()方法,用来比较好的处理深度对象的比较 参考链接: Github-underscore 样例展示: _...

Scfan的博客天涯 718

JavaScript .map() 的本质:纯函数式映射与工程实践指南

.map() 是 JavaScript 中实现数组到数组确定性转换的核心高阶函数,其本质是纯函数式映射(pure mapping)——不修改原数组、无外部副作用、严格返回新数组。它遵循输入→输出的数学映射原理,区别于遍历型操作如 forEach 或 for 循环。技术价值在于提升代码可预测性、支持链式组合、增强类型安全与可测试性,并天然适配函数式编程范式。典型应用场景包括 React 列表渲染、数据格式标准化、TS 类型推导转换及 Map/Set 等类数组结构迁移处理。理解 .map() 的契约边界(如禁止

weixin_33970449的博客 350

JavaScript类型本质:值的语义系统与运行时契约

在编程语言中,‘类型’并非变量的标签,而是为内存中的原始比特赋予可计算意义的语义系统。它决定了值如何被解释、转换与操作,是连接人类逻辑与机器执行的核心桥梁。JavaScript作为动态类型语言,其类型绑定于值而非变量,依赖运行时的隐式转换与契约式行为,这既带来灵活性,也引入不确定性。理解IEEE 754浮点数、UTF-16字符串、原型链对象等底层映射机制,是规避`0.1 + 0.2 !== 0.3`、`typeof null === 'object'`等经典陷阱的前提。本文深入剖析JS九种语言类型、三大检测

xiang_fu的博客 504

2024应届生找工作面试心得

这里分享每次的面试体会,不定期更新。面试中遇到的复习过的就不在这里解释了。真的头要秃了@*@

xhc6666的博客 1712

初学JavaScript之第一周学习

前话: JavaScript是什么 JavaScript是一门语言,和所有编程语言一样,能够有if, else, for, while,还有函数(方法),当然也可以自己定义函数(方法)。 JavaScript能做的事情主要有两方面: Web页面 在Web页面上,目前主要有三种元素:HTML, CSS, JavaScript。HTML类似于结构,你可以用HTML定义一些结构,包括header, f...

qq_35808394的博客 616
上一篇: 数据结构与算法之LRU: 实现 LRU 缓存算法功能 (Ts, Py, Go版)
下一篇: 前端小技巧: TS实现柯里化函数
Wang's Blog
博客等级 码龄12年 7438粉丝 2422原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wang's Blog

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值