Varun Chopra
Varun Chopra

Reputation: 55

Recursive JS issue

Thanks for helping in advance. Can you please help me find the mistake I am making in this code:

<script>
  function getChildrenRecursively(parent) {
    returnValue = [];
    var children = getChildren(parent);
    children.forEach(function(child, index, array) {
      itemData = new Object();
      itemData.id = parent + "_" + index + "_" + child;
      itemData.items = getChildrenRecursively(child);

      returnValue.push(itemData);
    })
    return returnValue;
  }

  function getChildren(parentId) {
    if (parentId == 1) return [2, 3];
    if (parentId == 2) return [4];
    if (parentId == 3) return [5, 6];
    if (parentId == 4) return [];
    if (parentId == 5) return [];
    if (parentId == 6) return [];
  }

  console.log(getChildrenRecursively(1));
</script>

getChildrenRecursively(parentId) is a recursive method that gathers children of passed parent id (by calling getChildren(parentId)) and then it calls itself recursively for each childid to gather children of children and so on. The output I expect from returnValue is this:

An array with 2 elements since parentId "1" has 2 children "2" and "3". Then "2" will have a subarray of 1 element "4" and "3" will have a subarray of 2 elements "5" and "6". But I get this and each subchild has 2 children and so on endlessely, please help me figure out the bug in code:

incorrect output

Upvotes: 0

Views: 44

Answers (2)

Sylwester
Sylwester

Reputation: 48745

function getChildrenRecursively(parent) {
  const children = getChildren(parent);
  const arrReturn = children.map(
      (child, index) => ({
          id: parent + "_" + index + "_" + child,
          items: getChildrenRecursively(child),
      }));
  return arrReturn;     
}

function getChildren(parentId) {
  switch (parentId) {
     case 1: return [2, 3];
     case 2: return [4];
     case 3: return [5, 6];
     default: return [];
  }
}

IMO there are still some issues with this. getChrildrenRecursively doesn't really get children, but builds a tree. With one adjustment it would include the root:

function getTree(parent) {
  function createNode(id, index = 0) {
      return {
          id: parent + "_" + index + "_" + id,
          items: getChildren(id).map(createNode);
      };
  }
  return createNode(parent);
}
console.log(getTree(1).items);

Upvotes: 0

John-Paul Ensign
John-Paul Ensign

Reputation: 141

See the changes below. I have added let and changed var to let. It appears that you have run into an issue known as Temporal Dead Zone (as described by Mozilla)

More information about it can be found here. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let

<script>
  function getChildrenRecursively(parent) {
    let returnValue = [];
    let children = getChildren(parent);
    children.forEach(function(child, index, array) {
      let itemData = new Object();
      itemData.id = parent + "_" + index + "_" + child;
      itemData.items = getChildrenRecursively(child);

      returnValue.push(itemData);
    })
    return returnValue;
  }

  function getChildren(parentId) {
    if (parentId == 1) return [2, 3];
    if (parentId == 2) return [4];
    if (parentId == 3) return [5, 6];
    if (parentId == 4) return [];
    if (parentId == 5) return [];
    if (parentId == 6) return [];
  }

  console.log(getChildrenRecursively(1));
</script>

Upvotes: 1

Related Questions