3

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.

1
  • Can you add a sample JSON? Commented Sep 6, 2019 at 6:28

3 Answers 3

1

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);
Sign up to request clarification or add additional context in comments.

Comments

0

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

1 Comment

or use for..of instead ...
0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.