【JS】tree数据查询

前言

作为苦逼的前端攻城狮,如果后端不愿意对数据进行处理,那么我们只能自给自足了~🚀
小编上周遇到了个需求:数据以树状的形式展开,且支持查询。
这个需求听起来很简单,但上手处理数据就发现了🙁对小编来讲,有点难度。
由于后端小伙不愿意返回符合查询条件的树状数据,那么这个重任只能交给无助的小编了~
🚀🚀🚀特此文章记录一下🚀🚀🚀

思路梳理

1.后端返回的是树状数据,所以我们首先需要将数据扁平化;

// 数据扁平化
const dealTreeData = (data: any) => {
  let arrTree: any = []
  data.forEach((ele: any) => {
    let obj = { ...ele }
    delete obj.children
    arrTree.push(obj)
    if (ele?.children?.length) {
      arrTree.push(...dealTreeData(ele.children))
    }
  });
  return arrTree;
}

2.筛选出符合条件的数据;

 let dealData = dealTreeData(treeData)
 let arr = dealData.filter((ele: any) => ele.isFilter)

3.根据筛选出来的数据,寻找数据所有父级;

  let res: any = [...arr] || []
  arr.forEach((x: any) => {
    let arrtemp = treeFindDataByFactor(treeData, (d: any) => d.label.indexOf(x.label) !== -1)
    arrtemp.forEach((y: any) => {
      res.push(y)
    })
  })

4.去重;

const result = Array.from(new Set(res.map(JSON.stringify)), JSON.parse);

5.将扁平数据转换成树状数据;

// 扁平数据转tree
const changeTreeData = (arr: any, parentId: number) => {
  function loop(parentId: number) {
    return arr.reduce((pre: any, cur: any) => {
      if (cur.pid === parentId) {
        cur.children = loop(cur.id)
        pre.push(cur)
      }
      return pre
    }, [])
  }
  return loop(parentId)
}

上硬菜(完整代码)

在这里插入图片描述

const treeData: any = [
  {
    id: 1,
    pid: 0,
    label: 'Item2',
    isFilter: true,
    children: [{
      id: 9,
      pid: 1,
      label: 'Item2-1',
      isFilter: false,
      children: []
    }, {
      id: 10,
      pid: 1,
      label: 'Item2-2',
      isFilter: false,
      children: [{
        id: 11,
        pid: 10,
        label: 'Item2-2-1',
        isFilter: false,
        children: [{
          id: 13,
          pid: 11,
          label: 'Item2-2-1-1',
          isFilter: false,
          children: []
        }]
      }, {
        id: 12,
        pid: 10,
        label: 'Item',
        isFilter: false,
        children: [{
          id: 14,
          pid: 12,
          label: 'Item2-2-2-1',
          isFilter: false,
          children: [{
            id: 15,
            pid: 14,
            label: 'Item2-2-2-1-1',
            isFilter: false,
            children: [{
              id: 16,
              pid: 15,
              label: 'Item2-2-2-1-1-1',
              isFilter: false,
              children: []
            }, {
              id: 17,
              pid: 15,
              label: 'Item2-2-2-1-1-2',
              isFilter: false,
              children: []
            }, {
              id: 18,
              pid: 15,
              label: 'Item2-2-2-1-1-3',
              isFilter: true,
              children: []
            }]
          },]
        }]
      }]
    }]
  }, {
    id: 2,
    pid: 0,
    label: 'Item3',
    isFilter: false,
    children: [{
      id: 19,
      pid: 2,
      label: 'Item3-1',
      isFilter: false,
      children: [{
        id: 22,
        pid: 19,
        label: 'Item3-1-1',
        isFilter: false,
        children: []
      }, {
        id: 23,
        pid: 19,
        label: 'Item3-1-2',
        isFilter: false,
        children: [{
          id: 28,
          pid: 23,
          label: 'Item3-1-2-1',
          isFilter: false,
          children: [{
            id: 29,
            pid: 28,
            label: 'Item3-1-2-1-1',
            isFilter: false,
            children: []
          }, {
            id: 30,
            pid: 28,
            label: 'Item3-1-2-1-2',
            isFilter: false,
            children: [{
              id: 32,
              pid: 30,
              label: 'Item3-1-2-1-3',
              isFilter: false,
              children: []
            },]
          }, {
            id: 31,
            pid: 28,
            label: 'Item3-1-2-1',
            isFilter: true,
            children: []
          },]
        },]
      },]
    }, {
      id: 20,
      pid: 2,
      label: 'Item3-2',
      isFilter: false,
      children: [{
        id: 24,
        pid: 20,
        label: 'Item3-2-1',
        isFilter: false,
        children: []
      },]
    }, {
      id: 21,
      pid: 2,
      label: 'Item3-3',
      isFilter: false,
      children: [{
        id: 25,
        pid: 21,
        label: 'Item3-3-1',
        isFilter: false,
        children: [{
          id: 26,
          pid: 25,
          label: 'Item3-3-1-1',
          isFilter: false,
          children: []
        }, {
          id: 27,
          pid: 25,
          label: 'Item3-3-1-2',
          isFilter: false,
          children: []
        },]
      },]
    },]
  },
]
// 数据扁平化
const dealTreeData = (data: any) => {
  let arrTree: any = []
  data.forEach((ele: any) => {
    let obj = { ...ele }
    delete obj.children
    arrTree.push(obj)
    if (ele?.children?.length) {
      arrTree.push(...dealTreeData(ele.children))
    }
  });
  return arrTree;
}
// 扁平数据转tree
const changeTreeData = (arr: any, parentId: number) => {
  function loop(parentId: number) {
    return arr.reduce((pre: any, cur: any) => {
      if (cur.pid === parentId) {
        cur.children = loop(cur.id)
        pre.push(cur)
      }

      return pre
    }, [])
  }
  return loop(parentId)
}


/**
 * 根据条件查询出树级结构的对应数据
 * @param tree 树结构数据
 * @param func 条件函数
 * @param findArr 找到的数据
 * @returns {{length}|[]|*|[]|*[]}
 */
const treeFindDataByFactor = (tree: any, func: any, findArr: any = []): [] => {
  if (!tree || !tree.length) {
    return [];
  }
  for (const data of tree) {
    let tempData = { ...data }
    delete tempData.children
    findArr.push(tempData);
    if (func(data)) {
      return findArr;
    }
    if (data.children && data.children.length) {
      const findChildren = treeFindDataByFactor(data.children, func, findArr);
      if (findChildren.length) return findChildren;
    }
    findArr.pop();
  }
  return [];
}

const filterData = (tree: any) => {
  let dealData = dealTreeData(tree)
  let arr = dealData.filter((ele: any) => ele.isFilter)

  let res: any = [...arr]||[]
  console.log('符合条件的数据:',arr)
  arr.forEach((x: any) => {
    let arrtemp = treeFindDataByFactor(treeData, (d: any) => d.label.indexOf(x.label) !== -1)
    arrtemp.forEach((y: any) => {
      res.push(y)
    })
  })
  const result = Array.from(new Set(res.map(JSON.stringify)), JSON.parse);

  console.log('去重后的数据:',result)
  return  changeTreeData(result, 0)

}
let treeResult=filterData(treeData)
console.log('初始数据:',treeData);
console.log('筛选条件:isFilter为true');
console.log('筛选数据:',treeResult);

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值