我正在试图理解递归,并且想要解决一个类似的问题:Recursively find all children from parent menu.

我的问题与上面示例中的问题之间的区别在于,我需要该函数的结果是叶 node 列表.因此,如果您使用下面的JSON数据,并且我想知道menuId["1005", "1007", "1009"]1的叶 node 是什么,我希望结果是["1005", "1007", "1009"].如果我想知道从["1005", "1007", "1009"]4开始的叶 node 是什么,我希望结果是["1007", "1009"]

[
    {"menuId":"1001","depth":"1","parentId":"0"},
    {"menuId":"1002","depth":"1","parentId":"0"},
    {"menuId":"1003","depth":"2","parentId":"1001"},
    {"menuId":"1004","depth":"2","parentId":"1001"},
    {"menuId":"1005","depth":"3","parentId":"1003"}, 
    {"menuId":"1006","depth":"3","parentId":"1004"}, 
    {"menuId":"1007","depth":"4","parentId":"1006"}, 
    {"menuId":"1008","depth":"4","parentId":"1006"}, 
    {"menuId":"1009","depth":"5","parentId":"1008"},
]

我试着修改链接中的代码来解决我的问题,但我似乎弄不明白:

    function getChildren(array, id) {
    return array.reduce((r, { menuId }) => {
        if (array.filter(x => x.parentId === id).length === 0) {
            r.push(menuId);
        } else {
            getChildren(array, menuId)
        }
        return r;
    }, []);

如有任何建议或帮助,我们将不胜感激.

推荐答案

编辑:重新制作,因为我不识字.

考虑到您拥有的数据 struct 是线性化的,递归不是一种非常有效的方法.因此,我首先将数据转换为实际的树 struct ,在这种 struct 中递归可以大放异彩.

问题是您没有合适的树,因为根 node 丢失了.我还假设您不希望更改您的输入数据,因此我以非 destruct 性的方式克隆了您的数据.允许更改items个数据(添加children属性)而不是复制并插入虚拟根 node 将大大简化代码.

const items = [
    {"menuId":"1001","depth":"1","parentId":"0"},
    {"menuId":"1002","depth":"1","parentId":"0"},
    {"menuId":"1003","depth":"2","parentId":"1001"},
    {"menuId":"1004","depth":"2","parentId":"1001"},
    {"menuId":"1005","depth":"3","parentId":"1003"}, 
    {"menuId":"1006","depth":"3","parentId":"1004"}, 
    {"menuId":"1007","depth":"4","parentId":"1006"}, 
    {"menuId":"1008","depth":"4","parentId":"1006"}, 
    {"menuId":"1009","depth":"5","parentId":"1008"},
];

const tree = {};
function treeify(items) {
  const roots = [];
  const lookup = {};
  for (const item of items) {
    lookup[item.menuId] = { ...item, children: [] };
  }
  for (const item of Object.values(lookup)) {
    if (item.parentId in lookup) {
      lookup[item.parentId].children.push(item);
    } else {
      roots.push(item);
    }
  }
  return roots;
}

function leafNodes(root) {
  if (root.children.length) {
    return root.children.flatMap(leafNodes);
  } else {
    return [root];
  }
}

const roots = treeify(items);
const node1001 = roots.find(item => item.menuId == "1001");
const leafNodesOf1001 = leafNodes(node1001);
console.log(leafNodesOf1001);
console.log(leafNodesOf1001.map(item => item.menuId));
// ["1005", "1007", "1009"]

Javascript相关问答推荐

防止用户在selectizeInput中取消 Select 选项

MongoDB中的引用

google docs boldText直到按行执行应用脚本错误

在我的html表单中的用户输入没有被传送到我的google表单中

为什么按钮会随浮动属性一起移动?

用于编辑CSS样式的Java脚本

如何在每次单击按钮时重新加载HighChart/设置HighChart动画?

使用Java脚本导入gltf场景并创建边界框

在Java中寻找三次Bezier曲线上的点及其Angular

在使用REACT更改了CSS类之后,无法更改CSS样式

无法避免UV:flat的插值:非法使用保留字"

FileReader()不能处理Firefox和GiB文件

MongoDB通过数字或字符串过滤列表

在JavaScript中将Base64转换为JSON

如何将字符串拆分成单词并跟踪每个单词的索引(在原始字符串中)?

我们是否可以在reactjs中创建多个同名的路由

如何从Reaction-Redux中来自API调用的数据中筛选值

Rails 7:在不使用导入映射的情况下导入Java脚本

带元素数组的Mongo聚合

JavaScript structuredClone在Chrome/Edge中获得了非法调用,但在NodeJS中没有