tree 树形数据,扁平化数组,数组转树形结构父子级数据,模糊搜索,筛选,尾递归

23 篇文章 0 订阅
4 篇文章 0 订阅

概要

提示:树形数据搜索,筛选

整体架构流程

提示:根据搜索条件筛选树形数据
区域IsCheck固定为false,通过判断筛选后的数据有无 设备子级 再进行筛选
树形数据:

var tree = [{
        id: '01',
        parentId:'#',
        modeltype:'area',
        IsCheck :'false',
        text: '区域1',
        children: [{
            id: '011',
            parentId:'01',
        	modeltype:'area',
        	IsCheck :'false',
            text: '区域2',
            children: [
                {
                    id: '0111',
                    parentId:'001',
                    text: '设备1',
        			modeltype:'meter',
        			IsCheck :'false',
                    children: [],
                }, {
                    id: '0112',
                    parentId:'001',
                    text: '设备2',
       				modeltype:'meter',
        			IsCheck :'true',
                    children: [],
                },
            ],
        }],
    }]

模糊搜索,子级与其上级,或区域父级

bindHandleTreeData(tree ,'设备1',{ children: "children"; text: "text" })

 /**
   * 搜索设备
   * @param treeData 树形参数
   * @param searchValue 搜索参数
   * @param fieldNames 树形数据结构-字段-看需求
   * @returns
   */
  const bindHandleTreeData: any = (
    treeData: any,
    searchValue: any,
    fieldNames: { children: "children"; text: "text" }
  ) => {
    if (!treeData || treeData.length === 0) {
      return [];
    }
    const array = [];
    for (let i = 0; i < treeData.length; i += 1) {
      if (
        bindHandleTreeData(
          treeData[i][fieldNames.children],
          searchValue,
          fieldNames
        ).length > 0 ||
        treeData[i][fieldNames.text].includes(searchValue)
      ) {
        array.push({
          ...treeData[i],
          [fieldNames.children]: bindHandleTreeData(
            treeData[i][fieldNames.children],
            searchValue,
            fieldNames
          ),
        });
      }
    }
    return array;
  };

树形数据扁平化-转数组(利于筛选)看需求

// 转数组
  const getArray = (data: any[]) => {
    var fun = (data: { [x: string]: any }) => {
      var a: any[] = [];
      for (var i in data) {
        var item = data[i];
        var obj: any = new Object();
        for (var j in item) {
          if (j !== "children") {
            obj[j] = item[j];
          }
        }
        a.push(obj);
        if (item.children && item.children.length > 0) {
          a = a.concat(fun(item.children));
        }
      }
      return a;
    };
    var list = fun(data);
    return list;
  };

将扁平化后的树形数据,转树形结构数据

搜索IsCheck === false

//扁平化数据
let cloneData=getArray(tree)
//筛选符合需求的数据(item.IsCheck === false)
let meterData = cloneData.filter((item) => {
        return item.IsCheck === false;
      });
if (meterData.length) {
        data = getTree(meterData, "#");
      }
 //最后结果
 console.log(data)  
   /**
   * 转树形
   * @param list 扁平化数据
   * @param parentId 父id 最顶级父id默认 parentId=#
   * @returns 
   */
  const getTree = (list: any[], parentId: any) => {
    let fun = (parentId: any) => {
      let parent = parentId ? parentId : "#";
      let b = [];
      for (let i in list) {
        let item = list[i];
        if (item.parent === parent) {
          item.children = fun(item.id);
          // 清除无设备 -区域-看需求(不展示无设备子级元素的区域)
          if (item.children.length === 0 && item.modeltype === "area") {
            item["disableCheckbox"] = true;
            item["IsCheck"] = true;
          } else {
            b.push(item);
          }
        }
      }
      return b;
    };
    return fun(parentId);
  };

( 尾递归)将扁平化后的树形数据,转树形结构数据

什么是尾递归

尾递归是指一个函数在调用自身之后不再执行任何其他操作,而是将返回值直接传递给函数调用的上级,从而避免了新的调用栈帧的创建。换句话说,尾递归是指递归调用发生在函数的最后一个语句中,从而使得函数调用不需要保存多个调用栈帧,而只需一个即可


const data = [
    { id: 1, name: '节点1', parent: "#"},
    { id: 2, name: '节点2', parent: 1 },
    { id: 3, name: '节点3', parent: 1 },
    { id: 4, name: '节点4', parent: 2 },
]

const data2=arrayToTree(data)

  /**
   * 递归2.0
   * @param array
   * @param parentId
   * @returns
   */
  const arrayToTree = (array: any[], parentId = "#") => {
    const treeData: any[] = [];

    const findChildren = (parentId: any) => {
      return array.filter((item) => item.parent === parentId);
    };

    const buildTree = (nodeList: any[], parentNode: any | null) => {
      nodeList.forEach((node: { id: null }) => {
        if (parentNode === "#") {
          treeData.push({ ...node });
        } else {
          let children = parentNode.children || [];
          children.push({ ...node });
          parentNode.children = children;
        }

        const childNodes = findChildren(node.id);

        if (childNodes.length > 0) {
          buildTree(childNodes, node);
        }
      });
    };

    buildTree(findChildren("#"), "#");

    return treeData;
  };

输出结果:

[{
    "id": 1,
    "name": "节点1",
    "parent": '#',
    "children": [{
        "id": 2,
        "name": "节点2",
        "parent": 1,
        "children": [{
            "id": 4,
            "name": "节点4",
            "parent": 2
        }]
    },{
        "id": 3,
        "name": "节点3",
        "parent": 1
    }]
}]

尾递归
在这里插入图片描述

区域IsCheck固定为false,通过判断筛选后的数据有无 设备子级 再进行筛选

搜索IsCheck === true

 /**
   * 获取IsCheck === true设备父级
   * @param list 数据
   * @param parentId 父id
   * @returns
   */
  const getTreeBind = (list: any[], parentId: any) => {
    let b: any[] = [];
    let fun = (parentId: any) => {
      let parent = parentId ? parentId : "#";
      for (let i in list) {
        let item = list[i];
        if (parent === item.id) {
          if (item.parent !== "#") {
            b.push(item.id);
            fun(item.parent);
          } else {
            b.push(item.id);
          }
        }
      }
      return b;
    };
    return fun(parentId);
  };
//扁平化数据
let cloneData=getArray(tree)

    let data: any[] = [];
    let meter: any[] = [];
    let data2 = cloneData;
    let data1 = data2.filter((item) => {
      // 判断文字
      if (item.modeltype === "area") {
        return item.IsCheck === false;
      } else {
        return item.IsCheck === true;
      }
    });

    data1.forEach((item) => {
      if (item.modeltype !== "area") {
        meter.push(item.id);
        if (item.parent !== "#") {
          //搜索父级 getTreeBind
          let filterData = getTreeBind(data1, item.parent);
          meter = concat(meter, filterData);
        }
      }
    });
    data1 = data1.filter((item) => {
      return meter.includes(item.id);
    });
    if (data1.length !== 0) {
      data = getTree(data1, "#");
    }

小结

提示:总结
1、模糊搜索
2、根据需求进行数据处理
3、递归2.0 尾递归

JavaScript 将树形结构转换一维数组(递归),转树形数据

  • 10
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值