Ganesh
Ganesh

Reputation: 103

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.

Upvotes: 3

Views: 72

Answers (3)

Munna Bhakta
Munna Bhakta

Reputation: 353

Here are corrected code. You had used return findObjectByUid in inner calling by which code was terminating before completing loop.

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

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,[]);

Upvotes: 0

Nina Scholz
Nina Scholz

Reputation: 386550

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

Upvotes: 1

Sumit
Sumit

Reputation: 4252

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 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. Example:

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

Upvotes: 0

Related Questions