JavaScript 实现树形结构和一维数组互相转换

news2025/1/24 17:48:41

背景

树形结构和一维数组是开发中很容易碰到的情况,也是面试中很容易碰到的手撕题目
在这里插入图片描述

实现

一、一维数组转树形结构

FROM

const source = [
  { id: 1, name: "张三", pid: 0 },
  { id: 2, name: "李四", pid: 1 },
  { id: 3, name: "王五", pid: 2 },
  { id: 4, name: "赵六", pid: 3 },
  { id: 5, name: "陈七", pid: 4 },
  { id: 6, name: "谢八", pid: 4 },
  { id: 7, name: "林一", pid: 1 },
  { id: 8, name: "杨二", pid: 3 },
];

TO

[
  {
    "id": 1,
    "name": "张三",
    "pid": 0,
    "children": [
      {
        "id": 2,
        "name": "李四",
        "pid": 1,
        "children": [
          {
            "id": 3,
            "name": "王五",
            "pid": 2,
            "children": [
              {
                "id": 4,
                "name": "赵六",
                "pid": 3,
                "children": [
                  {
                    "id": 5,
                    "name": "陈七",
                    "pid": 4
                  },
                  {
                    "id": 6,
                    "name": "谢八",
                    "pid": 4
                  }
                ]
              },
              {
                "id": 8,
                "name": "杨二",
                "pid": 3
              }
            ]
          }
        ]
      },
      {
        "id": 7,
        "name": "林一",
        "pid": 1
      }
    ]
  }
]

迭代实现

const buildTree = (root) => {
  const hash = {};
  const tree = [];
  root.forEach((node) => {
    hash[node.id] = node;
  });
  root.forEach((node) => {
    const parent = hash[node.pid];
    if (parent) {
      (parent.children || (parent.children = [])).push(node);
    } else {
      tree.push(hash[node.id]);
    }
  });
  return tree;
}
const tree = buildTree(source);
console.log(JSON.stringify(tree, null, 2));

递归实现

const buildTree = (root, pid = 0) => {
  const tree = [];
  for (const node of root) {
    if (node.pid === pid) {
      const children = buildTree(root, node.id);
      if (children.length) {
        node.children = children;
      }
      tree.push(node);
    }
  }
  return tree;
};
const tree = buildTree(source);
console.log(JSON.stringify(tree, null, 2));

二、树形结构拍平

// 展平树状数组
const node = {
  id: 0,
  parentId: null,
  name: "生物",
  children: [
    {
      id: 1,
      parentId: 0,
      name: "动物",
      children: [
        {
          id: 4,
          parentId: 1,
          name: "哺乳动物",
          children: [
            {
              id: 8,
              parentId: 4,
              name: "大象",
            },
            {
              id: 9,
              parentId: 4,
              name: "海豚",
            },
            {
              id: 10,
              parentId: 4,
              name: "猩猩",
            },
          ],
        },
        {
          id: 5,
          parentId: 1,
          name: "卵生动物",
          children: [
            {
              id: 11,
              parentId: 5,
              name: "蟒蛇",
            },
            {
              id: 12,
              parentId: 5,
              name: "麻雀",
            },
          ],
        },
      ],
    },
    {
      id: 2,
      parentId: 0,
      name: "植物",
      children: [
        {
          id: 6,
          parentId: 2,
          name: "种子植物",
          children: [
            {
              id: 111,
              parentId: 6,
              name: "种子植物的孩子1",
            },
            {
              id: 112,
              parentId: 6,
              name: "种子植物的孩子2",
            },
          ],
        },
        {
          id: 7,
          parentId: 2,
          name: "蕨类植物",
        },
      ],
    },
    {
      id: 3,
      parentId: 0,
      name: "微生物",
    },
  ],
};
// 展平
[
  { id: 0, parentId: null, name: "生物" },
  { id: 1, parentId: 0, name: "动物" },
  { id: 2, parentId: 0, name: "植物" },
  { id: 3, parentId: 0, name: "微生物" },
  { id: 4, parentId: 1, name: "哺乳动物" },
  { id: 5, parentId: 1, name: "卵生动物" },
  { id: 6, parentId: 2, name: "种子植物" },
  { id: 7, parentId: 2, name: "蕨类植物" },
  { id: 8, parentId: 4, name: "大象" },
  { id: 9, parentId: 4, name: "海豚" },
  { id: 10, parentId: 4, name: "猩猩" },
  { id: 11, parentId: 5, name: "蟒蛇" },
  { id: 12, parentId: 5, name: "麻雀" },
  { id: 111, parentId: 6, name: "种子植物的孩子1" },
  { id: 112, parentId: 6, name: "种子植物的孩子2" },
];
const treeToFlat = (root) => {
  let res = [];
  let queue = [root];
  while (queue.length) {
    const node = queue.shift();
    res.push({
      id: node.id,
      parentId: node.parentId,
      name: node.name,
    });
    if (node.children) {
      for (const child of node.children) {
        queue.push(child);
      }
    }
  }
  return res;
};

console.log(treeToFlat(node));

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/965580.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【【STM32--28--IO引脚的复用功能】】

STM32–28–IO引脚的复用功能 STM32的IO复用功能 何为复用? 我们先了解一下何为通用 IO端口的输入或输出是由GPIO外设控制,我们称之为通用 复用: IO端口的输入或者是输出是由其他非GPIO外设控制就像经常说的USART 由 DR寄存器进行输出 STM32的IO复用功…

Python学习教程:集合操作的详细教程

前言 大家早好、午好、晚好吖 ❤ ~欢迎光临本文章 Python中有两种可以遍历的容器类型: 序列类型:包含字符串、列表、元祖 序列类型是线性表,就像数组一样,是在内存中开辟一块连续空间,连续存储的, 那么查找…

前端vue3+ts架构

1、vue creat 项目名称 选择自定义 选择需要的依赖 选择vue3 一路enter,选择eslistprettier 继续enter,等待安装 按步骤操作,项目启动成功 2、vscode安装5款插件 2、代码保存自动格式化,保证每个开发人员代码一致,根目…

震惊!靠「职业骗薪」,在上海买了别墅

昨天在知乎热榜上看到一条新闻,震惊之余,也有点可叹可悲的感觉。 根据经济观察报的报道:职业骗薪者,3 年在沪买别墅,同时供职 16 家公司却从不上班,落网时她还在面试。 新闻上说:管悦被警察抓获…

Bert和LSTM:情绪分类中的表现

一、说明 这篇文章的目的是评估和比较 2 种深度学习算法(BERT 和 LSTM)在情感分析中进行二元分类的性能。评估将侧重于两个关键指标:准确性(衡量整体分类性能)和训练时间(评估每种算法的效率)。…

OpenCV(十六):高斯图像金字塔

目录 1.高斯图像金字塔原理 2.高斯图像金字塔实现 1.高斯图像金字塔原理 高斯图像金字塔是一种用于多尺度图像表示和处理的重要技术。它通过对图像进行多次高斯模糊和下采样操作来生成不同分辨率的图像层级,每个层级都是原始图像的模糊和降采样版本。 以下是高斯…

系统中出现大量不可中断进程和僵尸进程(理论)

一 进程状态 当 iowait 升高时,进程很可能因为得不到硬件的响应,而长时间处于不可中断状态。从 ps 或者 top 命令的输出中,你可以发现它们都处于 D 状态,也就是不可中断状态(Uninterruptible Sleep)。 R …

Python Opencv实践 - 轮廓检测

import cv2 as cv import numpy as np import matplotlib.pyplot as pltimg cv.imread("../SampleImages/map.jpg") print(img.shape) plt.imshow(img[:,:,::-1])#Canny边缘检测 edges cv.Canny(img, 127, 255, 0) plt.imshow(edges, cmapplt.cm.gray)#查找轮廓 #c…

【C++代码】找出字符串中第一个匹配项的下标,重复的子字符串--代码随想录

题目:找出字符串中第一个匹配项的下标 给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串的第一个匹配项的下标(下标从 0 开始)。如果 needle 不是 haystack 的一部分,则返回 -1 。 题…

地理测绘基础知识(4) 照射计算上篇

我们接着上一篇来推导。 照射计算,是一种常用的三维几何计算。已知一个光源的光强图,计算光源投射到地表各处的功率密度。这种计算需求可以直观的理解为计算已知位置、指向、聚光特性的手电筒,计算地表某地点强度。当然,如果穷尽地…

mysql使用st_distance_sphere函数报错Incorrect arguments to st_distance_sphere

最近发现执行mysql st_distance_sphere报错了。 报错的信息是Incorrect arguments to st_distance_sphere。 最开始以为是跟mysql的版本有关系,所以看了下自己本地的mysql版本,执行一下sql select version(); 发现自己本地的mysql版本是 5.7.30 这…

FFmpeg报错:Connection to tcp://XXX?timeout=XXX failed: Connection timed out

一、现象 通过FFmpeg(FFmpeg的版本是5.0.3)拉摄像机的rtsp流获取音视频数据,执行命令: ./ffmpeg -timeout 3000000 -i "rtsp://172.16.17.156/stream/video5" 报错:Connection to tcp://XXX?timeoutXXX …

JavaScript 生成 16: 9 宽高比

这篇文章只是对 for 循环一个简单应用,没有什么知识含量。 可以跳过这篇文章。 只是我用来保存一下我的代码,保存在本地我嫌碍眼,总想把他删了。 正文部分 公式:其中 width 表示宽度,height 表示高度 16 9 w i d t…

CLIP改进工作串讲(bryanyzhu)内容记录

文章目录 分割Language-driven semantic segmentation - ICLR2022GroupViT: Semantic Segmentation Emerges from Text Supervision 目标检测ViLD : Open-vocabulary object detection via vision and language knowledge distillation 视觉定位GLIP:Grounded Language-Image P…

VsCode搭建Java开发环境 vscode搭建java开发环境 vscode springboot 搭建springboot

VsCode搭建Java开发环境 vscode搭建java开发环境 vscode springboot 搭建springboot VsCode java开发截图1、安装Java 环境相关插件2、安装 Spring 插件3、安装 Mybatis 插件第一个 vsc-mybatis第二个 mybatisX 4、安装Maven环境4.1、安装Maven环境4.2、VsCode配置Maven环境 5、…

使用Python进行Base64编码和解码

假设您有一个想要通过网络传输的二进制图像文件。您很惊讶对方没有正确接收该文件 - 该文件只是包含奇怪的字符! 嗯,您似乎试图以原始位和字节格式发送文件,而所使用的媒体是为流文本而设计的。 避免此类问题的解决方法是什么?答…

Interspeech 2023 | 火山引擎流媒体音频技术之语音增强和AI音频编码

背景介绍 为了应对处理各类复杂音视频通信场景,如多设备、多人、多噪音场景,流媒体通信技术渐渐成为人们生活中不可或缺的技术。为达到更好的主观体验,使用户听得清、听得真,流媒体音频技术方案融合了传统机器学习和基于AI的语音增…

微服务--Seata(分布式事务)

TCC模式在代码中实现:侵入性强,并且的自己实现事务控制逻辑 Try,Confirm() cancel() 第三方开源框架:BeyeTCC\TCC-transaction\Himly 异步实现:MQ可靠消息最终一致性 GlobalTransacational---AT模式

Threejs里反向播放动画

在Blender里给对象添加了一个动画后,假设是在帧1到帧40添加的动画帧,那么正常播放时是从帧1到帧40,反向播放则是从帧40到帧1,本文讲述如何在Threejs里方向播放Blender里添加的动画。 一 添加动画 之前文章中已经讲述如何在Blende…

MAC ITEM 解决cd: string not in pwd的问题

今天使用cd 粘贴复制的路径的时候,报了这么一个错. cd: string not in pwd eistert192 Library % cd Application Support cd: string not in pwd: Application eistert192 Library % 让人一脸懵逼. 对比一下,发现中文路径里的空格截断了路径 导致后面的路径就没有办法被包含…