【study】关于el-tree相关的数组操作

107 阅读4分钟
  1. 什么是广度优先遍历?
  • 是一种用于遍历或搜索树或图的算法。它从根节点开始,逐层遍历节点,先访问根节点,然后访问根节点的所有子节点,再访问子节点的子节点,以此类推,直到遍历完所有节点。

  • 广度优先遍历通常使用队列数据结构来实现。具体步骤如下:

    1. 将根节点放入队列中。
    1. 从队列中取出一个节点,访问该节点。
    1. 将该节点的所有未访问过的子节点放入队列中。
    1. 重复步骤2和步骤3,直到队列为空。
  • 广度优先遍历保证了在同一层级的节点会先被访问,然后才是下一层级的节点。这种遍历方式适用于寻找最短路径、查找特定节点等问题。

// 将一维数据变成el-tree需要的多维数组

// 思路: 将服务端返回的平级数组,处理成tree需要的多层结构
//       使用循环和哈希表来实现,定义一个arr和map遍历原始数组 arr
//       将每个节点存储到哈希表 map 中再次遍历arr,根据 parentId 找到其父节点
//       并将当前节点添加到父节点的 children 属性中
//       如果节点没有 parentId,则将其作为根节点添加到 tree 
//       数组中最后返回tree 

//广度优先遍历
 function convertToTree(arr) {
        const tree = [];
        const map = {};
        arr.forEach(item => {
            map[item.id] = {
              label: item.label,
              id: item.id,
              children: []
            };
        });
        arr.forEach(item => {
            const node = map[item.id];
            if (item.parentId) {
               const parent = map[item.parentId];
               parent.children.push(node);
            } else {
               tree.push(node);
            }
        });
            return tree;
        }

        const flatArray = [
        { id: 1, label: 'Node 1', parentId: null },
        { id: 2, label: 'Node 1.1', parentId: 1 },
        { id: 3, label: 'Node 1.2', parentId: 1 },
        { id: 4, label: 'Node 1.2.1', parentId: 3 },
        { id: 5, label: 'Node 2', parentId: null },
        { id: 6, label: 'Node 2.1', parentId: 5 },
        { id: 7, label: 'Node 2.2', parentId: 5 },
        ];

        const treeData = convertToTree(flatArray);
        console.log(treeData);
        

// 递归
function convertToTree(arr, parentId = null) {
         const tree = [];
         arr.forEach(item => {
         if (item.parentId === parentId) {
            const children = convertToTreeRecursive(arr, item.id);
            if (children.length > 0) {
                item.children = children;
             }
            tree.push(item);
         }
      });
    return tree;
  }

const treeData = convertToTree(flatArray);
console.log(treeData);

image.png

// 将el-tree(多维数组)打平成一维数组
 const data = [{
            id: 1111,
            label: 'Node 1',
            children: [{
                   id: 2,
                   label: 'Node 1.1'
                },
                {
                   id: 345,
                   label: 'Node 1.2',
                children: [
                {
                    id: 4,
                    label: 'Node 1.2.1',
                }
                ]
                }
            ],
        },{
            id: 565,
            label: 'Node 2',
            children: [{
                   id: 69,
                   label: 'Node 2.1'
                },
                {
                   id: 78,
                   label: 'Node 2.2',
                }
            ],
        }
    ]
  
  
 // 广度优先遍历
 
 // 没有节点parentId
 function flattenData(data) {
      const flatArray = [];
      const stack = [...data];

      while (stack.length > 0) {
        const node = stack.shift();
        flatArray.push({
          id: node.id,
          label: node.label,
        });

        if (node.children && node.children.length > 0) {
          stack.push(...node.children);
        }
      }

      return flatArray;
    }
    
 // 有节点parentId
 function flattenData(data) {
      const flatArray = [];
      const stack = data.map(node => ({ ...node, parentId: null }));

      while (stack.length > 0) {
        const { id, label, children, parentId } = stack.shift();
        flatArray.push({
          id,
          label,
          parentId
        });

        if (children && children.length > 0) {
          stack.push(...children.map(child => ({ ...child, parentId: id })));
        }
      }
      return flatArray;
    }

console.log(flattenData(data));

// 递归
function flattenData(data) {
        const flatArray = [];

        function flatten(node) {
            flatArray.push({
            id: node.id,
            label: node.label,
            parentId: node.parentId
            });

            if (node.children && node.children.length > 0) {
            node.children.forEach(child => {
                flatten({
                ...child,
                parentId: node.id
                });
            });
            }
        }

        data.forEach(node => {
            flatten(node);
        });

        return flatArray;
        }

    console.log(flattenData(data))

image.png

// el-tree 里面的slot ,插入节点的上移下移,前端通过点击实现视图的变化(即实现上下移动)

const obj = {
          id: 122,
          label: 'Node 1.2.2',
          level: 3,
          sequence: 2,
          parentId: 12,
      }
const data = [
{
    id: 1,
    label: 'Node 1',
    level: 1,
    sequence: 1,
    parentId: null,
    children: [
      {
        id: 11,
        label: 'Node 1.1',
        level: 2,
        sequence: 1,
        parentId: 1,
      },
      {
        id: 12,
        label: 'Node 1.2',
        level: 2,
        sequence: 2,
        parentId: 1,
        children: [
          {
            id: 121,
            label: 'Node 1.2.1',
            level: 3,
            sequence: 1,
            parentId: 12,
          },
          {
            id: 122,
            label: 'Node 1.2.2',
            level: 3,
            sequence: 2,
            parentId: 12,
          },
          {
            id: 123,
            label: 'Node 1.2.3',
            level: 3,
            sequence: 3,
            parentId: 12,
          },
        ]
      },
      {
        id: 13,
        label: 'Node 1.3',
        level: 2,
        sequence: 3,
        parentId: 1,
      },
    ],
  },
  {
    id: 2,
    label: 'Node 2',
    level: 1,
    sequence: 1,
    parentId: null,
    children: [
      {
        id: 21,
        label: 'Node 2.1',
        level: 2,
        sequence: 1,
        parentId: 2,
      },
      {
        id: 22,
        label: 'Node 2.2',
        level: 2,
        sequence: 2,
        parentId: 2,
      },
      {
        id: 23,
        label: 'Node 2.2',
        level: 2,
        sequence: 3,
        parentId: 2,
      },
      {
        id: 24,
        label: 'Node 2.4',
        level: 2,
        sequence: 4,
        parentId: 2,
      },
    ],
  }
];

// 上下移动
let targetArray = null;
function findParent(array, parentId) {
  for (let i = 0; i < array.length; i++) {
    const item = array[i];
    if (item.id === parentId) {
      targetArray = item.children;
      break;
    }
    if (item.children) {
      findParent(item.children, parentId);
    }
  }
}

findParent(data, obj.parentId);

console.log("找到的数组:", targetArray);


if (targetArray.length > 0) {
  const index = targetArray.findIndex(item => item.id === obj.id);
  // 上移
  // if (index > 0) {
  //   console.log('上移')
  //   const temp = targetArray[index];
  //   targetArray[index] = targetArray[index - 1];
  //   targetArray[index - 1] = temp;
  // }
  // 下移
  if (index < targetArray.length - 1) {
    console.log('下移')
    const temp = targetArray[index];
    targetArray[index] = targetArray[index + 1];
    targetArray[index + 1] = temp;
  }
}

console.log("last数组:", data);

image.png

// el-tree 里面的slot ,插入节点编辑,替换掉原tree数组里面的内容
const obj = {
          id: 122,
          label: '替换显示的内容',
          level: 3,
          sequence: 2,
          parentId: 12,
      }
const data = [
{
    id: 1,
    label: 'Node 1',
    level: 1,
    sequence: 1,
    parentId: null,
    children: [
      {
        id: 11,
        label: 'Node 1.1',
        level: 2,
        sequence: 1,
        parentId: 1,
      },
      {
        id: 12,
        label: 'Node 1.2',
        level: 2,
        sequence: 2,
        parentId: 1,
        children: [
          {
            id: 121,
            label: 'Node 1.2.1',
            level: 3,
            sequence: 1,
            parentId: 12,
          },
          {
            id: 122,
            label: 'Node 1.2.2',
            level: 3,
            sequence: 2,
            parentId: 12,
          },
          {
            id: 123,
            label: 'Node 1.2.3',
            level: 3,
            sequence: 3,
            parentId: 12,
          },
        ]
      },
      {
        id: 13,
        label: 'Node 1.3',
        level: 2,
        sequence: 3,
        parentId: 1,
      },
    ],
  },
  {
    id: 2,
    label: 'Node 2',
    level: 1,
    sequence: 1,
    parentId: null,
    children: [
      {
        id: 21,
        label: 'Node 2.1',
        level: 2,
        sequence: 1,
        parentId: 2,
      },
      {
        id: 22,
        label: 'Node 2.2',
        level: 2,
        sequence: 2,
        parentId: 2,
      },
      {
        id: 23,
        label: 'Node 2.2',
        level: 2,
        sequence: 3,
        parentId: 2,
      },
      {
        id: 24,
        label: 'Node 2.4',
        level: 2,
        sequence: 4,
        parentId: 2,
      },
    ],
  }
];

// 广度优先遍历
function replaceData(data, obj) {
  const newData = [...data];
  const stack = [...newData];

  while (stack.length > 0) {
    const item = stack.pop();

    if (item.id === obj.id) {
      Object.assign(item, obj);
    }

    if (item.children) {
      stack.push(...item.children);
    }
  }

  return newData;
}

console.log(replaceData(data,obj))

// 递归
function replaceData(array, targetObj) {
  for (let i = 0; i < array.length; i++) {
    const item = array[i];
    if (item.id === targetObj.id) {
      array[i] = targetObj;
      break;
    }
    if (item.children) {
      replaceData(item.children, targetObj);
    }
  }
}

replaceData(data, obj);

console.log("替换后的数组:", data);

image.png