5.手写JavaScript数组和树互相转换

一、核心思想

1.数组转树

(1)循环遍历

1.定义临时对象和结果数组分别遍历存储数组中的对象和最终返回结果

2.遍历传入的数组

3.如果父在临时对象中不存在 将父加入到结果数组中

4.否则将当前对象加入到当前对象父id的children数组中

5.返回结果

(2)递归

1.定义数组存储返回结果

2.深拷贝一个数组用来循环遍历与val相等的父id

3.如果存在 则递归找到孩子并将其加入当前父id的children数组中

4.返回结果

2.树转数组

利用广度优先遍历实现树到数组,定义返回结果和队列,当队列非空时遍历队列,将当前队列的第一项出队,如果当前项有孩子则循环遍历将孩子加入队尾,循环遍历到结束,返回结果。

二、代码实现

1.数组转树

(1)循环遍历
const arr = [
  { id: "00", name: "测试", pid: "", job: "测试" },
  { id: "01", name: "张大", pid: "", job: "项目经理" },
  { id: "02", name: "小亮", pid: "01", job: "产品leader" },
  { id: "03", name: "小美", pid: "01", job: "UIleader" },
  { id: "04", name: "老马", pid: "01", job: "技术leader" },
  { id: "05", name: "老王", pid: "01", job: "测试leader" },
  { id: "06", name: "老李", pid: "01", job: "运维leader" },
  { id: "07", name: "小丽", pid: "02", job: "产品经理" },
  { id: "09", name: "小高", pid: "03", job: "UI设计师" },
  { id: "10", name: "小刘", pid: "04", job: "前端工程师" },
  { id: "13", name: "小赵", pid: "05", job: "测试工程师" },
  { id: "15", name: "小涛", pid: "06", job: "运维工程师" },
];
/**
 * 循环将数组转换为树
 * @param {Array} array 传入数组
 * @return {Array} result 返回数组
 */
function arrayToTree(array){
  //定义临时对象和结果数组分别遍历存储数组中的对象和最终返回结果
  let tempObj = {},result = []
  //遍历传入的数组
  result = array.reduce((prev,cur)=>{
    cur.children = []
    tempObj[cur.id] = cur //浅拷贝
    if (!tempObj[cur.pid]) {
      //如果父在临时对象中不存在 将父加入到结果数组中
       prev.push(cur)
    } else {
        //否则将当前对象加入到当前对象父id的children数组中
      tempObj[cur.pid].children.push(cur)
    }
    return prev
  },[])
   //返回结果
  return result
}
console.log(arrayToTree(arr))
(2)递归
const arr = [
  { id: "00", name: "测试", pid: "", job: "测试" },
  { id: "01", name: "张大", pid: "", job: "项目经理" },
  { id: "02", name: "小亮", pid: "01", job: "产品leader" },
  { id: "03", name: "小美", pid: "01", job: "UIleader" },
  { id: "04", name: "老马", pid: "01", job: "技术leader" },
  { id: "05", name: "老王", pid: "01", job: "测试leader" },
  { id: "06", name: "老李", pid: "01", job: "运维leader" },
  { id: "07", name: "小丽", pid: "02", job: "产品经理" },
  { id: "09", name: "小高", pid: "03", job: "UI设计师" },
  { id: "10", name: "小刘", pid: "04", job: "前端工程师" },
  { id: "13", name: "小赵", pid: "05", job: "测试工程师" },
  { id: "15", name: "小涛", pid: "06", job: "运维工程师" },
];
function arrayToTreeByRecursion(array, val) {
  //定义数组存储返回结果
  let result = [];
  //深拷贝一个数组用来循环遍历与val相等的父id
  let arr = JSON.parse(JSON.stringify(array));
  arr.forEach((item) => {
    //如果存在 则递归找到孩子并将其加入当前父id的children数组中
    if (item.pid == val) {
      let children = arrayToTreeByRecursion(arr, item.id);
      children.length ? (item.children = children) : (item.children = []);
      result.push(item);
    }
  });
  //返回结果
  return result;
}
let newTree = arrayToTreeByRecursion(arr, "")
console.log("newTree",newTree)

2.树转数组

let tree = [
  {
    id: "00",
    job: "测试",
    name: "测试",
    pid: "",
    children: [],
  },
  {
    id: "01",
    job: "项目经理",
    name: "张大",
    pid: "",
    children: [
      {
        id: "02",
        name: "小亮",
        pid: "01",
        job: "产品leader",
        children: [
          { id: "07", name: "小丽", pid: "02", job: "产品经理", children: [] },
        ],
      },
      {
        id: "03",
        name: "小美",
        pid: "01",
        job: "UIleader",
        children: [
          { id: "09", name: "小高", pid: "03", job: "UI设计师", children: [] },
        ],
      },
      {
        id: "04",
        name: "老马",
        pid: "01",
        job: "技术leader",
        children: [
          {
            id: "10",
            name: "小刘",
            pid: "04",
            job: "前端工程师",
            children: [],
          },
        ],
      },
      {
        id: "05",
        name: "老王",
        pid: "01",
        job: "测试leader",
        children: [
          {
            id: "13",
            name: "小赵",
            pid: "05",
            job: "测试工程师",
            children: [],
          },
        ],
      },
      {
        id: "06",
        name: "老李",
        pid: "01",
        job: "运维leader",
        children: [
          {
            id: "15",
            name: "小涛",
            pid: "06",
            job: "运维工程师",
            children: [],
          },
        ],
      },
    ],
  },
];
/**
 * 利用广度优先遍历实现树到数组
 * @param {Array} tree 传出的树
 * @return {Array} result 返回结果
 */
function treeToArray(tree) {
  //定义返回结果和队列
  let result = [],
    queue = tree;
  //当队列非空时遍历队列
  while (queue.length) {
    //将当前队列的第一项出队
    let target = queue.shift();
    result.push({
      id: target.id,
      name: target.name,
      pid: target.pid,
      job: target.job,
    });
    //如果当前项有孩子则循环遍历将孩子加入队尾
    if (target.children.length) {
      target.children.forEach((item) => {
        queue.push(item);
      });
    }
  }
  //循环遍历到结束
  //返回结果
  return result;
}
console.log(treeToArray(newTree));

  • 8
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值