首页 > 其他分享 >【手写系列】手把手教你如何实现 列表转树-树转列表

【手写系列】手把手教你如何实现 列表转树-树转列表

时间:2023-07-31 10:34:05浏览次数:40  
标签:children name pid 树转 item 转树 列表 id

这个应该算是前端中经常出现的业务场景,不过大部分都是由组件库帮助你做好了这些事情

如果要是让你自己来实现,你又会如何实现呢?

今天,我们就来好好讲解下这两个需求该如何去写,在知道如何用的情况下,也要知道如何实现它们。

从这篇文章你能学到(复习)什么东西

  1. JS中Map的用法
  2. 递归解法
  3. hasOwnProperty
  4. JSON.Stringify
  5. JSON.parse

树转列表该如何实现

这个使用场景应该是较为常见的,如果给你一个树结构,需要你从中搜索到某一子项,你就可以这样做。

直接将树结构转成列表,那么搜索起来的效率也会比较高,时间复杂度就是O(n)

我目前能想到的解法是-深度遍历,代码实现如下

const tree = [
  {
    id: 1,
    name: "部门1",
    pid: 0,
    children: [
      {
        id: 2,
        name: "部门2",
        pid: 1,
      },
      {
        id: 3,
        name: "部门3",
        pid: 1,
        children: [
          {
            id: 4,
            name: "部门4",
            pid: 3,
            children: [
              {
                id: 5,
                name: "部门5",
                pid: 4,
              },
            ],
          },
        ],
      },
    ],
  },
  {
    id: 6,
    name: "部门6",
    pid: 0,
  },
];

const transformTreeToList = (tree) => {
  const result = [];
  const fn = (tree) => {
    for (const item of tree) {
      result.push({
        id: item.id,
        name: item.name,
        pid: item.pid,
      });
      if (!item.children || item.children.length === 0) continue;
      fn(item.children);
    }
  };
  fn(tree);
  return result;
};

const data = transformTreeToList(tree);
console.log("列表数据", data);

我们从transformTreeToList这个函数开始看。

首先需要对树进行遍历,最关键的步骤是判断当前项是否有孩子,有孩子的话,则需要进入下一层,没有的话则需要进入到下一次,不执行fn(item.children)

整体来讲,这个数转列表比较好写,类似与这种递归解法,最重要的核心是找到结束条件

不知道大家有没有更好的解决办法呢,有的话欢迎评论留言(~ ̄▽ ̄)~

列表转树 该如何实现

在列表转树,提供给你一个带有pid对象,这个pid就是指向它的上一层的id。

在我们实现嵌套层级展示的时候,列表转树就非常有用了。

接下来,来看下我是怎么实现的~

let arr = [
  { id: 1, name: "部门1", pid: 0 },
  { id: 2, name: "部门2", pid: 1 },
  { id: 3, name: "部门3", pid: 1 },
  { id: 4, name: "部门4", pid: 3 },
  { id: 5, name: "部门5", pid: 4 },
  { id: 6, name: "部门6", pid: 0 },
];

const listToTree = (list) => {
  const hashMap = new Map();
  // 深拷贝原始数据,防止我们的修改影响原始数据
  const newList = JSON.parse(JSON.stringify(list));
  // 将数据全部存入到map中去
  newList.forEach((item) => {
    hashMap.set(item.id, item);
  });
  newList.forEach((item) => {
    if (hashMap.has(item.pid)) {
      const parent = hashMap.get(item.pid);
      if (parent.hasOwnProperty("children")) {
        parent.children.push(item);
      } else {
        parent.children = [item];
      }
    }
  });

  return newList.filter((item) => item.pid === 0);
};

console.log(listToTree(arr), arr);

是不是看上去比较简单,这种解法应该是最优解了,如果大家还有其他解法,欢迎在评论区留言。

我们来分析下。

1️⃣ 我们需要用到MapMap 对象保存键值对,并且能够记住键的原始插入顺序。任何值(对象或者基本类型)都可以作为一个键或一个值。

2️⃣ 我们先将列表数据依次存入到Map对象中去,列表的数据id作为key,列表的数据整体作为值。

3️⃣ 然后我们需要newList在进行遍历,这一次主要是判断在map中是否有对应的pid的值,如果有的话,则说明,当前项是属于id为pid的孩子,我们就需要将当前值放到id为pid的对象中去。

4️⃣ 在这样操作完之后,我们需要过滤出pid为0的值,因为pid为0意味着它是第一级,也是我们需要的数据。

总结一下,其实我们是利用了 Map的取值的时间复杂度是O(1), 无需遍历,效率比较高,我们只用了一次循环,就可以把这个项放到对应的父亲下面。

标签:children,name,pid,树转,item,转树,列表,id
From: https://www.cnblogs.com/codespirit-zx/p/17592787.html

相关文章

  • 匹配工具2:IP前缀列表
    [Huawei]ipip-prefixname[indexindex-number]{permit|deny}ip-addressmask-length[greater-equalgreater-equal-value][less-equalless-equal-value]NAME参数是本IP前缀列表的名称INDEX关键字及参数指示本表项在IP前缀列表中的序号(或索引号),该关键字及参数是......
  • 16、博客列表加载效果 - 博客界面改造文章(202307)
    最近闲来无事,就想着把博客界面弄得再有点动画效果,于是就找了延迟函数,把博客的内容列表加载的动画写出来了。      该动画效果还是挺炫的,但是因为刷新页面,下面列表的显示需要拉动到底下才看到,所以这里只能记录一下了。      下面是实现的函数:       ......
  • Day09_列表类型
    1.list()类型转换用法和作用: 2.列表操作:正向取值、反向去之、可取也可以改、索引不存在则报错: 3.列表操作:列表追加值: 4.列表操作:列表插入值: 5.列表操作:extend用法两个列表元素合并、字符串合并到列表中: 6.列表操作:列表删除方式一del: 7.列表操作:列表删除方......
  • 【Python】使用 pyecharts 模块绘制动态时间线柱状图 ① ( 列表排序 | 使用 sorted 函
    文章目录一、列表排序1、使用sorted函数对容器进行排序2、使用list.sort函数对列表进行排序3、使用list.sort函数对列表进行排序-设置排序函数4、使用list.sort函数对列表进行排序-设置lambda匿名排序函数pyecharts画廊网站:https://gallery.pyecharts.org/#/......
  • 如何在 Python 中计算列表中的唯一值?
    Python提供了各种方法来操作列表,这是最常用的数据结构之一。使用列表时的一项常见任务是计算其中唯一值的出现次数,这在数据分析、处理和筛选任务中通常是必需的。在本文中,我们将探讨四种不同的方法来计算Python列表中的唯一值。在本文中,我们将介绍如何使用集合模块中的集合、字......
  • 详情页返回列表缓存定位实现
    VUE2vue版本^2.6.111.App页面<template><divid="app"><keep-alive:include="aliveList"><router-view/></keep-alive></div></template><script>importstorefrom'.......
  • 散列表的查找
    散列表的查找基本思想记录的存储位置与关键字之间存在的对应关系.使用哈希函数查找对应的数据就是直接将学生的学号当做下标来存储.这样就非常好查找如何让查找根据散列函数H(key)=k查找key=n,则访问H(n)=n的地址,若内容为n则成功.若查询不到,返回一个特殊值,空指针......
  • 把操作列表变成下拉框要加点击事件是什么
     element-ui中的:         <el-table-columnlabel="操作"width="200px">         <templateslot-scope="scope">          <el-selectplaceholder="选择">           &......
  • 筛选出 1指定行( 编号中包含login的行),2指定列的值 放到列表中
    第一版 写死了列的值的下标,不够人性化,还需要去数列在第几个位置#导包importxlrd#第一步根据包提供的方法读某个路径下的xlsworkbook=xlrd.open_workbook('../data/testcase.xls')#第二步根据名字找某个表每个excel里有Sheet1Sheet2等worksheet=wor......
  • 5.6for与两个列表
     ......