【问题标题】:Return a value from loop in recursive function从递归函数的循环中返回一个值
【发布时间】:2016-03-23 12:03:27
【问题描述】:

我需要在树中按 id 查找节点。为此,我将在两个嵌套循环的帮助下下降。但返回未定义。

function searchInTreeById(node, matchingId) {
    var res;
    if (node.select('id').get() == matchingId) {
        res = node.get();
        return res
    } else {
        if (node.exists('childObjects')) {
            node.select('childObjects').map(function (cursor, i) {
                cursor.select('children').map(function (cursorChild, j) {

                    if (cursorChild.select('id').get() === matchingId) {
                        // console.log(cursorChild.get()) //this console.log is execute
                        res = cursorChild.get();
                        return res;
                    } else {
                        // console.log(cursorChild.get())
                        searchInTreeById(cursorChild, matchingId)
                    }
                })
            })
        } else {
            res = node;
        }
    }
    return res
}

【问题讨论】:

  • 忽略searchInTreeById的结果看起来很可疑(不确定“猴面包树”是什么,所以不管它是什么都可以)
  • @AlexeiLevenkov 如果我设置 res=searchInTreeById(cursorChild, matchingId),然后 func 返回最后访问的节点...
  • 旁注:map 通常是错误的搜索方式——很可能还有另一个函数(类似于Array.find)允许在中间停止迭代。

标签: javascript recursion baobab


【解决方案1】:

如果没有立即找到匹配项,则递归调用最终应该返回结果的函数。但事实并非如此。

searchInTreeById(cursorChild, matchingId);

但是,使用 map 会将检查/功能应用于每个孩子,但在这种情况下,结果无论如何都会丢失。 map 函数将参数中给出的函数应用于数组元素,并为每个元素返回新值 - 一个新数组。根据找到项目的速度,在内存中构建树的副本(传统的递归函数只保留元素的路径直到节点)。

因此,您可以将映射结果分配给一个数组,如果该特定子项没有匹配项,则每个元素都设置为 null,如果没有匹配项,则设置为 node成立。然后检查创建的数组的所有元素,如果找到则返回 nullnode (然后,调用者在该级别填充数组等...)。

你也可以使用全局变量

var found = null;

仅在匹配时设置(否则不执行任何操作)。由于似乎 map 是不可破坏的,因此无论如何都会检查该级别的子级。但是,不同的是,在再次递归调用函数之前,您检查全局变量,如果 found 仍然为空,则调用 only

但也许 map 可以一起避免?

不使用 map,而是将子元素聚集在一个数组中并遍历该数组,递归调用函数,并立即返回匹配的节点。

建议的代码(未测试)

function searchInTreeById(node, matchingId) {
    if (node.select('id').get() == matchingId) {
        return node.get();
    }
    if (node.exists('childObjects')) {
         var list = node.select('childObjects');
         for(var i=0 ; i<list.length ; i++) {
             var res = searchInTreeById(list[i], matchingId);
             if (res) return res;
         }
     }
     return null;
}

免责声明:猴面包树第一个计时器。 (虽然我读了this

【讨论】:

  • 非常感谢!!!!我稍微修改了这段代码,它应该是这样工作的!
  • 那么你改变了什么,使用全局变量?在数组中获取地图结果?迭代孩子?
  • 遍历childrens并改变部件,与猴面包树连接?像这样: var list = parentNode.select('childObjects').get();
猜你喜欢
  • 2014-10-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-02
  • 2014-05-01
  • 2012-10-16
  • 2021-06-11
相关资源
最近更新 更多