【问题标题】:Recursive function returning undefined value返回未定义值的递归函数
【发布时间】:2019-09-06 17:10:37
【问题描述】:

我想从多层结构中获取对象

我为它编写了函数,但即使在返回时它也没有从函数中出来并返回值,它会继续下一次递归。我知道它对先前调用的函数的返回值,并且由于它的作用域是阻止它被覆盖,这就是返回未定义值的原因

  var selectedObj = findObjectByUid( existingStructure, selectedUid);
function findObjectByUid( root, selectedUid ) {
    if( root.uniqueId === selectedUid ) {
        return root;
    }
    if( root.children && root.children.length > 0 ) {
        for( var k in root.children ) {
            if( root.children[ k ].uniqueId === selectedUid ) {
                return root.children[ k ];
            } else if( root.children.length ) {
                return findObjectByUid( root.children[ k ], selectedUid );
            }
        }
    }
}

在这里,我想在匹配 uid 时回到我的初始调用函数。

【问题讨论】:

  • 你能添加一个示例 JSON 吗?

标签: javascript


【解决方案1】:

实际上,无论找到的节点如何,您都会返回第一个孩子。

您可以获取一个临时变量并存储子项检查的结果,如果不是 falsy,则返回此值。

顺便说一句,您可以直接将数组的子元素用于递归。

function findObjectByUid(root, selectedUid) {
    if (root.uniqueId === selectedUid) return root;
    if (!root.children || !root.children.length) return;
    for (let child of root.children) {
        let temp = findObjectByUid(child, selectedUid);
        if (temp) return temp;
    }
}

var selectedObj = findObjectByUid(existingStructure, selectedUid);

【讨论】:

    【解决方案2】:

    在数组上使用这种方法存在三个问题。首先,如果这些属性是可枚举的,那么 for...in 还会遍历对象的原型属性。例如:

    Array.prototype.voice = "James Earl Jones";
    
    var tMinus = [
      "Two",
      "One",
      "Blast off!"
    ];
    
    var countdown = "";
    
    for (var step in tMinus) {
      countdown += tMinus[step] + "\n";
    }
    
    console.log(countdown);
    // => "Two
    //    One
    //    Blast Off!
    //    James Earl Jones
    //    "
    

    这可以通过使用 hasOwnProperty 排除原型属性来解决。 示例:

    for (var step in tMinus) {
      if (tMinus.hasOwnProperty(step)) {
        countdown += tMinus[step] + "\n";
      }
    }
    

    【讨论】:

    【解决方案3】:

    这里是更正的代码。您在内部调用中使用了return findObjectByUid,代码在完成循环之前终止。

    function findObjectByUid( root, selectedUid ,foundArr) {
    
      if( root.uniqueId === selectedUid ) {
        foundArr.push(root);
          return root;
      }
      else if( root.children && root.children.length > 0 ) {
          for( var k in root.children ) {
               findObjectByUid( root.children[k], selectedUid,foundArr ); 
              if(root.children[k]=== selectedUid){break;}
          }
      }
       return foundArr.length>0?foundArr[0]:null;
    }
    

    示例json和调用方法

    var root = {uniqueId:1,children:[{uniqueId:10},{uniqueId:11,children:[{uniqueId:21,children:[]},{uniqueId:22,children:[]},{uniqueId:23,children:[{uniqueId:31,children:[]},{uniqueId:32,children:[]}]}]},{uniqueId:12,children:[]},{uniqueId:13,children:[]}]};
    findObjectByUid(root,32,[]);
    

    【讨论】:

      猜你喜欢
      • 2013-07-05
      • 2012-09-26
      相关资源
      最近更新 更多