js树形结构数据处理

18 篇文章 0 订阅
2 篇文章 0 订阅

1.递归处理


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

function convert(list) {
  // 定义一个递归函数,接受一个节点作为参数,返回它的子树
  function buildTree(node) {
    // 创建一个空数组,用来存放子节点
    let children = []
    // 遍历数组,找到当前节点的子节点,并递归调用buildTree函数
    for (let item of list) {
      if (item.pid === node.id) {
        children.push(buildTree(item))
      }
    }
    // 如果子节点不为空,就给当前节点添加children属性
    if (children.length > 0) {
      node.children = children
    }
    // 返回当前节点
    return node
  }
  
  // 创建一个空数组,用来存放根节点
  let res = []
  // 遍历数组,找到根节点,并调用buildTree函数
  for (let item of list) {
    if (item.pid === 0) {
      res.push(buildTree(item))
    }
  }
  // 返回结果数组
  return res
}

2.reduce函数处理

      function convert(list) {
        let res = [];
        // 使用reduce方法遍历数组,创建一个maps对象,将数组中的每个元素以id为键,元素本身为值,存入maps对象中
        // reduce方法接受一个回调函数和一个初始值作为参数
        // 回调函数接受四个参数:累计值,当前值,当前索引,原数组
        // 回调函数的返回值会作为下一次调用的累计值
        // 初始值是一个空对象,表示maps对象的初始状态
        let maps = list.reduce((res, v) => ((res[v.id] = v), res), {});
        console.log(maps, "map2");
        // console.timeEnd()
        // 使用for...of循环遍历数组,对于每个元素item,判断它的pid是否为0,如果是,说明它是根节点,直接将它push到res数组中;如果不是,说明它有父节点,那么通过maps对象找到它的父节点parent,并在parent上创建或获取一个children属性,将item push到parent.children中
        for (const item of list) {
          console.log(item, "item");
          if (item.pid === 0) {
            res.push(item);
            continue;
          }
          if (item.pid in maps) {
            const parent = maps[item.pid];
            parent.children = parent.children || [];
            parent.children.push(item);
          }
        }
        // console.log(map,'map');
        // 返回res数组作为最终结果
        return res;
      }

3.eS6语法和高阶函数

function convert(list) {
  // 创建一个map对象,存放id和元素的映射关系
  // 使用list.map方法,将数组中的每个元素转换成一个数组,包含id和元素本身
  // 使用new Map方法,将这个数组转换成一个map对象
  let map = new Map(list.map(item => [item.id, item]))
  // 使用filter方法过滤出根节点,同时使用forEach方法给每个元素添加children属性
  // filter方法接受一个回调函数作为参数,返回一个新的数组,包含满足回调函数条件的元素
  // 回调函数接受三个参数:当前值,当前索引,原数组
  // 回调函数的返回值是一个布尔值,表示是否保留当前元素
  // forEach方法接受一个回调函数作为参数,对数组中的每个元素执行一次回调函数
  // 回调函数接受三个参数:当前值,当前索引,原数组
  // 回调函数没有返回值,只是对数组中的元素进行操作
  return list.filter(item => {
    // 如果pid为0,说明是根节点,直接返回true
    if (item.pid === 0) return true
    // 否则,通过map对象找到父节点,并将当前元素push到父节点的children中
    let parent = map.get(item.pid)
    parent.children = parent.children || []
    parent.children.push(item)
    // 返回false,表示不是根节点
    return false
  })
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值