JS树形数据常用递归方法总结

在使用element ui的tree组建的时候经常需要对tree进行递归操作,去获取树形数据中的某些值,下面总结了常用的一些方法

根据树形数据找出节点id为指定值的节点

function findNodeById(treeData, nodeId) {
    
    
  // 遍历当前层级的所有节点
  for (var i = 0; i < treeData.length; i++) {
    
    
    var node = treeData[i];
    // 如果当前节点的 ID 匹配目标节点的 ID,则返回当前节点
    if (node.id === nodeId) {
    
    
      return node;
    }
    // 如果当前节点有子节点,则递归调用当前函数继续查找子节点
    if (node.children && node.children.length > 0) {
    
    
      var foundNode = findNodeById(node.children, nodeId);
      // 如果在子节点中找到了目标节点,则返回找到的节点
      if (foundNode) {
    
    
        return foundNode;
      }
    }
  }
  
  // 如果遍历完所有节点仍未找到目标节点,则返回 null
  return null;
}
  
  // 如果遍历完所有子节点仍未找到目标节点,则返回 null
  return null;
}

根据根节点的id将一个一维数组转变为树形数据

rootValue即根节点的id

function transListToTreeData(list, rootValue) {
    
    
  // 思路:先找到所有的根节点,然后再再去添加children,第二个参数是根节点的pid值
  var arr = [];
  list.forEach((item) => {
    
    
    if (item.pid === rootValue) {
    
    
      const children = transListToTreeData(list, item.id);
      if (children.length) {
    
    
        // 如果children的长度大于0就说明找到了子节点
        item.children = children;
      }
      arr.push(item);
    }
  });
  return arr;
}

获取树形根节点的status 值为currentStatus的根节点的节点个数

    function getRootNodeByStatusCount(treeData,currentStatus){
    
    
      let count = 0;
      if (treeData && treeData.length) {
    
     // 判断数据是否存在并且不为空
        for (let i = 0; i < treeData.length; i++) {
    
     // 遍历子节点
          const node = treeData[i];
          if (node.status == currentStatus) {
    
     // 如果当前节点的 status 为 0,count 加一
            count++;
          }
          if (node.children && node.children.length > 0) {
    
     // 如果当前节点存在子节点,则递归遍历子节点
            count += getRootNodeByStatusCount(node.children,currentStatus);
          }
        }
      }
      return count;
    },

获取根节点的个数

    function getRootNodeCount(treeData) {
    
    
      if (!Array.isArray(treeData)) {
    
    
        return 0;
      }

      let count = 0;
      for (const node of treeData) {
    
    
        // 如果当前节点没有子节点,则累加计数器
        if (!node.children) {
    
    
          count++;
        }

        if (Array.isArray(node.children)) {
    
    
          // 如果节点有子节点,对其进行递归处理
          count += this.getRootNodeCount(node.children);
        }
      }

      return count;
    },

根据传入的id数组,给该节点添加一个disabled属性值为false,其他节点添加一个disabled属性值为true

      function disableTreeNodes(treeData, idArray) {
    
    
        if (!Array.isArray(treeData)) {
    
    
          return;
        }

        for (const node of treeData) {
    
    
          if (idArray.includes(node.id)) {
    
    
            // 如果当前节点在 idArray 数组中,则继续递归它的子节点
            // if (Array.isArray(node.children)) {
    
    
            node.disabled = false;
            disableTreeNodes(node.children, idArray);
            // }
          } else {
    
    
            // 否则将当前节点设为禁用状态,并递归它的子节点
            node.disabled = true;
            if (Array.isArray(node.children)) {
    
    
              disableTreeNodes(node.children, idArray);
            }
          }
        }
      },

返回根节点status属性值为status的节点树

    function filterRootNodes(data,status) {
    
    
      if (!data || data.length === 0) {
    
     // 判断数据是否存在并且不为空,如果是,则直接返回空数组
        return [];
      }
      const filteredData = []; // 定义过滤后的数据数组
      for (let i = 0; i < data.length; i++) {
    
     // 遍历每个节点
        const node = data[i];
        if (node.status == status) {
    
    
          filteredData.push(node);
        }
        if (node.children && node.children.length > 0) {
    
     // 如果当前节点存在子节点,则递归遍历子节点
          const filteredChildren = filterRootNodes(node.children,status); // 对子节点进行递归过滤
          if (filteredChildren.length > 0) {
    
     // 如果过滤后的子节点不为空,则将该节点加入到过滤后的数据数组中,并将过滤后的子节点作为其 children 属性的值
            filteredData.push({
    
    
              name: node.name,
              id:node.id,
              children: filteredChildren,
            });
          }
        }
      }
      return filteredData;
    },

测试数据:

[{
    
    
          label: '一级 1',
          children: [{
    
    
            label: '二级 1-1',
            children: [{
    
    
              label: '三级 1-1-1',
              status:1,
            }]
          }]
        }, {
    
    
          label: '一级 2',
          children: [{
    
    
            label: '二级 2-1',
            children: [{
    
    
              label: '三级 2-1-1',
              status:1,
            }]
          }, {
    
    
            label: '二级 2-2',
            children: [{
    
    
              label: '三级 2-2-1',
              status:0,
            }]
          }]
        }, {
    
    
          label: '一级 3',
          children: [{
    
    
            label: '二级 3-1',
            children: [{
    
    
              label: '三级 3-1-1',
              status:1,
            }]
          }, {
    
    
            label: '二级 3-2',
            children: [{
    
    
              label: '三级 3-2-1',
              status:0,
            }]
          }]
        }]

返回数据:

[{
    
    
          label: '一级 1',
          children: [{
    
    
            label: '二级 1-1',
            children: [{
    
    
              label: '三级 1-1-1',
              status:1,
            }]
          }]
        }, {
    
    
          label: '一级 2',
          children: [{
    
    
            label: '二级 2-1',
            children: [{
    
    
              label: '三级 2-1-1',
              status:1,
            }]
          }]
        }, {
    
    
          label: '一级 3',
          children: [{
    
    
            label: '二级 3-1',
            children: [{
    
    
              label: '三级 3-1-1',
              status:1,
            }]
          }]
        }]

Guess you like

Origin blog.csdn.net/ksjdbdh/article/details/131038988