JS数组和树形结构的相互转换

文章介绍了如何使用JavaScript将具有parentId字段的数组转换为树形结构,以及如何将树形结构转换回一维数组。主要方法包括创建源映射对象和使用广度优先搜索策略。提供了具体的代码示例来完成这两个转换过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、数组转为树形结构

1.数组形如下所示

[
  { parentId: -1, name: "商品管理", id: 1, auth: "cart" },
  { parentId: 1, name: "商品列表", id: 4, auth: "cart-list" },
  { parentId: -1, name: "添加管理员", id: 10, auth: "admin" },
];

2.将待处理数据(一维数组)根据 parentId 字段值处理成树形结构存入 menus 变量中。

数据处理成形如下格式(每一项都必须有 children 字段,没有子级时,children 为空数组):

[
  {
    parentId: -1,
    name: "商品管理",
    id: 1,
    auth: "cart",
    children: [
      {
        parentId: 1,
        name: "商品列表",
        id: 4,
        auth: "cart-list",
        children: [],
      },
    ],
  },
  {
    parentId: -1,
    name: "添加管理员",
    id: 10,
    auth: "admin",
    children: [],
  },
];

3.解决方案★★★★★

新建一个对象sourceMap,用数组里每个子项的id作为改对象的键值,每次循环子项,与该对象sourceMap进行比对,若子项的parentId值为“-1”,则直接将子项push到menus中;否则比对子项的parentId值与对象中的某键值,如若sourceMap[item.parentId]存在,说明该子项是该键值内的子节点,将该子项插入该对象的children中,因引用的原因,子项item内也相应改变,最终循环结束,返回menus数组,完成转换。

代码如下:

//测试数据
let menuList = [
  { parentId: -1, name: "添加管理员", id: 10, auth: "admin" },
  { parentId: 10, name: "管理员权限分配", id: 11, auth: "admin-auth" },
  { parentId: -1, name: "商品管理", id: 1, auth: "product" },
  { parentId: 1, name: "商品列表", id: 4, auth: "productList" },
  { parentId: 4, name: "商品分类", id: 5, auth: "category" },
  { parentId: 5, name: "添加分类", id: 8, auth: "addClassification" },
  { parentId: 4, name: "商品上架", id: 6, auth: "product" },
  { parentId: -1, name: "评论管理", id: 2, auth: "comments" },
  { parentId: -1, name: "个人中心", id: 3, auth: "profile" },
];

/**
 * @param {*} menuList 传入的数据
 * @return {*} menus 转化后的树形结构数据
 */

function getTree(menuList) {
  let menus=[]    //返回的树结构
  let sourceMap={}    //用传进来的每个项的id作为键值,建立一棵树
  menuList.forEach(item=>{
    item.children=[]
    sourceMap[item.id]=item    //浅拷贝,共享引用

    if(item.parentId==-1)
    {
      menus.push(item)
    }
    else
    {
      if(sourceMap[item.parentId])
      {
        sourceMap[item.parentId].children.push(item)
      }
    }
  })
  return menus; // menus 转化后的树形结构数据
};

let Tree=getTree(menuList)

console.log(Tree)

 二、树形结构转为一维数组

1.树形结构如下所示

[
  {
    parentId: -1,
    name: "商品管理",
    id: 1,
    auth: "cart",
    children: [
      {
        parentId: 1,
        name: "商品列表",
        id: 4,
        auth: "cart-list",
        children: [],
      },
    ],
  },
  {
    parentId: -1,
    name: "添加管理员",
    id: 10,
    auth: "admin",
    children: [],
  },
];

2.将待处理数据(树形结构)根据 parentId 字段值处理成一维数组存入 data变量中。

数据处理成形如下格式(每一项的 children 字段去除):

[
  { parentId: -1, name: "商品管理", id: 1, auth: "cart" },
  { parentId: 1, name: "商品列表", id: 4, auth: "cart-list" },
  { parentId: -1, name: "添加管理员", id: 10, auth: "admin" },
];

3.解决方案★★★★★

使用广度优先搜索转存为一维数组

代码如下:

let menuList = [
  {
    parentId: -1,
    name: "商品管理",
    id: 1,
    auth: "cart",
    children: [
      {
        parentId: 1,
        name: "商品列表",
        id: 4,
        auth: "cart-list",
        children: [],
      },
    ],
  },
  {
    parentId: -1,
    name: "添加管理员",
    id: 10,
    auth: "admin",
    children: [],
  },
];

/**
 * @param {*} menuList 传入的树形结构数据
 * @return {*} data 转化后的一维数组
 */
function transArr(menuList) {
  let newMenuList= menuList
  let data = [] //返回的数组
  while (newMenuList.length !== 0) { //当循环结束时跳出循环
    let item = newMenuList.shift() //取出第一个元素
    data.push({
      parentId: item.parentId,
      name: item.name,
      id: item.id,
      auth: item.auth
    })
    let children = item.children // 取出该节点的孩子
    if (children) {
      for (let i = 0; i < children.length; i++) {
        newMenuList.push(children[i]) //将子节点加入到队列尾部
      }
    }
  }
  return data
}
console.log(transArr(menuList))

圆满完成!!!

撒花❀❀❀

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值