user8728932
user8728932

Reputation:

Trouble trying to loop a tree recursively

I'm trying to loop over a tree and it items in order to look for a node by its id, this is the code:

<!DOCTYPE html>
<meta charset="utf-8">
<html>
<head>
  <title>Hi there</title>
  <script>
    function getNode(node, id) {
      if (node.id === id) {
        return node;
      }
      if (node.items) {
        for (let x of node.items) {
          return getNode(x, id);
        }
      }
    }

    function load() {
      var nodes = [{
        id: 0,
        label: 'root',
        items: [{
          id: 1,
          label: 'one'
        }, {
          id: 2,
          label: 'two'
        }, {
          id: 3,
          label: 'three'
        }, {
          id: 4,
          label: 'four'
        }]
      }];
      var n = nodes[0];
      var node = getNode(n, 3);
      console.log(node);
    }

    window.onload = load();
  </script>
</head>
<body>
</body>
</html>

I'm facing the problem when I call load the recursive function returns undefined. Any hint on how to solve this?

Upvotes: 1

Views: 46

Answers (2)

Keming
Keming

Reputation: 253

You cannot do recursive on this because there is no "items" property of items[0], so the recursion stops when it comes to

{
    id: 1,
    label: "one"
}

and return undefined.

Upvotes: -2

Nicholas Tower
Nicholas Tower

Reputation: 84982

for (let x of node.items) {
  return getNode(x, id);
}

This will look at the very first item, and regardless of what it finds, it returns the result of getNode. So it walks down to the item with id=1, then returns undefined, and continues returning undefined back up the stack. It never moves on to the rest of the items (ie, the loop doesn't do anything).

Instead, it should return only if it found it, or move on to the next item.

function getNode(node, id) {
  if (node.id === id) {
    return node;
  }
  if (node.items) {
    for (let x of node.items) {
      var result = getNode(x, id);
      if (result) {
        return result; //<<---- only returning if we found it
      }
    }
  }
}

function load() {
  var nodes = [{
    id: 0,
    label: 'root',
    items: [{
      id: 1,
      label: 'one'
    }, {
      id: 2,
      label: 'two'
    }, {
      id: 3,
      label: 'three'
    }, {
      id: 4,
      label: 'four'
    }]
  }];

  var n = nodes[0];

  var node = getNode(n, 3);
  console.log(node);
}

load();

Upvotes: 5

Related Questions