简体   繁体   English

递归函数返回未定义的值

[英]Recursive function returning undefined value

I want to fetch the object from multi level structure 我想从多级结构中获取对象

I written function for it but even on return its not coming out from function and returning value, its continue with next recursion. 我为它编写了函数但是即使返回它不是从函数和返回值中出来的,它继续下一次递归。 I know its returning value to the previously called function and as its scope is block its getting overridden and that's why returning undefined value 我知道它返回到以前调用的函数的值,因为它的作用域阻止它被覆盖,这就是为什么返回未定义的值

  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 );
            }
        }
    }
}

Here i want to get back to my initial calling function when it got matching uid. 这里我想回到我的初始调用函数,当它匹配uid。

Actually you return with the first child, regardless of the found node. 实际上,无论找到的节点如何,您都会与第一个孩子一起返回。

You could take a temporary variable and store the result of the children check and if not falsy return this value. 您可以使用临时变量并存储子检查的结果,如果不是,则返回此值。

BTW, you could take the child directly of the array for the recursion. 顺便说一句,您可以直接将数组的子进行递归。

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);

There are three problems with using this approach on arrays. 在阵列上使用此方法有三个问题。 First, the for...in also iterates over an object's prototype properties if those properties are enumerable. 首先,如果这些属性是可枚举的,for ... in也会迭代对象的原型属性。 For example: 例如:

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
//    "

That can be solved by using hasOwnProperty to exclude prototype properties. 这可以通过使用hasOwnProperty来排除原型属性来解决。 Example: 例:

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

Here are corrected code. 这是更正后的代码。 You had used return findObjectByUid in inner calling by which code was terminating before completing loop. 您已经在内部调用中使用了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;
}

Sample json and calling method 示例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,[]);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM