1

背景

遍历树形结构的菜单,实现子菜单的添加与删除。
菜单的树形结构:

L`2O$LP5%(5VM$F~6K)9{DH.png

要实现的功能:

  1. 添加子菜单
    获取到的数据有:整个菜单树形结构的数据以及目前选中的父菜单的key。
    逻辑:遍历这棵多叉树,找到父结点,拼接好子结点的信息,再push到父结点的children中。
  2. 删除子菜单
    获取到的数据有:整个菜单树形结构的数据以及目前选中的菜单的key。
    逻辑:遍历这棵多叉树,找到选中菜单的父结点,再遍历父结点的子结点找到选中的结点,利用splice删除选中结点。

实现方法

这两种功能都需要遍历多叉树。
这就涉及到大家不愿去触碰的多叉树遍历了....刚开始是循环套循环套循环....看得自己都昏了。
后来鼓起勇气重新来过。

递归遍历多叉树

百度百科对递归的定义是:程序调用自身的编程技巧称为递归( recursion)。
而我对递归的理解就是把大问题切分成一个一个小问题。也就是不断缩小参数范围。
我在写递归函数的时候是分了三步。

  • 第一步 明确函数功能
    当然,在背景中已说明。遍历多叉树,找到父结点,拼接好子结点的信息,再push到父结点的children中。
  • 第二步 找到递归出口
    第一个出口是,节点为空;
    第二个出口是找到父结点执行完相应操作;
  • 第三步 缩小参数范围
    当父结点存在子节点时,又向下遍历子节点。

具体代码

export const addMenu = (node, fatherKey, newDirectoryTitle) => {
  if (!node) {
    return;
  }
  if(node.key === fatherKey) {
    const child = {
      type: `${node.key}-${node.childType}`,
      title: newDirectoryTitle,
      key: `${node.key}-${node.childType}`,
      childType: 0,
      children:[],
    }
    node.childType += 1;
    node.children.push(child);
    return;
  }
  if(node.children && node.children.length > 0) {
    for(let i =0 ;i < node.children.length; i++) {
      addMenu(node.children[i],fatherKey,newDirectoryTitle);
    }
  }
};

删除子菜单的方法其实也是差不多。只是其中的处理逻辑不一样。
回头再看看之前写的多叉树遍历,其实并不难,只是自己原来对它有了惯性的抗拒。


Lingo
18 声望7 粉丝