【问题标题】:Javascript recursion, foreach loop won't exit?Javascript递归,foreach循环不会退出?
【发布时间】:2018-04-25 15:03:46
【问题描述】:

我构建了一个简单的 Javascript 树视图,其中每个节点都有一个名称、一个子节点列表和一个 ID:

class Node {
  constructor(name, childNodes, id) {
    this.name = name;
    this.childNodes = childNodes;
    this.id = id;
  }
}

我的目标是创建一个函数“getNodeById(parent, id)”,它返回具有给定 ID 的节点。我尝试过使用递归方法,但一定有错误:

function getNodeById(currentNode, id) {
  if (currentNode.id === id) { console.log("found"); return currentNode; }
  currentNode.children.forEach(child => {
    console.log(child);
    return getNodeById(child, id);
  });
}

我的想法是,该函数将搜索 childNodes 并再次调用自己。当找到正确的节点时,它应该在 if 语句之后返回,然后在 foreach 循环中。该函数成功找到正确的节点,但它不会停止并返回该节点。这是调用 getNodeById(parent, 2); 时的输出

为什么“找到”后函数不退出?

【问题讨论】:

    标签: javascript recursion


    【解决方案1】:
    function getNodeById(currentNode, id) {
      if (currentNode.id === id) { console.log("found"); return currentNode; }
      for(node = 0; node < currentNode.children.length; node ++) {
        const foundNode = getNodeById(currentNode.children[node], id);
        if(foundNode) {
          return foundNode
        }
      }
      return undefined
    }
    

    这应该有效!

    【讨论】:

      【解决方案2】:

      您可以使用 Array#some 短路并返回存储的节点(如果找到)。

      some() 对数组中存在的每个元素执行一次 callback 函数,直到找到一个 callback 返回 truthy 值(转换为时变为 true 的值)一个布尔值)。

      function getNodeById(currentNode, id) {
          var node;
          if (currentNode.id === id) {
              return currentNode;
          }
          currentNode.children.some(child => node = getNodeById(child, id));
          return node;
      }
      

      【讨论】:

      • 完美运行,谢谢!我只是不太了解一些循环。据我所知,找到正确的节点后,循环将继续并返回空的“var node”。它是如何工作的?
      • 不,找到节点后,循环停止,因为返回值是真的。
      • 好吧,听起来不错,但是函数如何知道“Node”类的元素是真还是假?
      • 如果没有找到节点,该函数返回undefined,或者返回一个对象,即节点,这是一个真值。
      【解决方案3】:

      除了抛出异常之外,没有其他方法可以停止或中断 forEach() 循环。如果你需要这样的行为,forEach() 方法是错误的工具。

      可以通过以下方式提前终止:

      一个简单的循环

      for...of 循环

      Array.prototype.every()

      Array.prototype.some()

      Array.prototype.find()

      Array.prototype.findIndex() 其他 Array 方法:every()、some()、find() 和 findIndex() 使用返回真值的谓词测试数组元素,以确定是否需要进一步迭代。

      https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach

      【讨论】:

      • 哦,好的,谢谢!我认为 return 总是会破坏功能。
      • @Basti 在map 中,您的返回值将成为结果数组中的新值,而forEachmap,除非返回值从未使用过。 return 或者如果函数确实返回到将使用下一个元素调用函数的被调用者,则将其结束,而不管先前的答案如何,并且这发生在它返回根目录的每个级别。 someevery 在每次调用时都会检查结果,因为当他们知道最终结果时会短路。
      【解决方案4】:

      getNodeById() 不返回任何内容。您正在从 forEach() 采取的右箭头函数返回,并且没有做任何事情。使用 for 循环。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-04-02
        • 2013-01-13
        • 2021-10-20
        • 2012-10-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多