I am trying to write a recursive generator for an in order traversal.
class Tree {
*inOrderTraversal() {
function* helper(node) {
if (node.left !
helper(node.left);
does call the function and create the generator, but the generator function body is never executed because the generator is never advanced. To forward all of its values to the current generator, you can use the yield* keyword, which works just like the
for (let i of helper(this.root))
yield i;
you've used in your inOrderTraversal
method. And indeed, that should've been a yield*
just as well - or even better, there is no reason to make inOrderTraversal
a generator function when it can just be a normal method that returns a generator:
class Tree {
inOrderTraversal() {
function* helper(node) {
if (node.left !== null)
yield* helper(node.left);
yield node.value;
if (node.right !== null)
yield* helper(node.right);
}
return helper(this.root);
}
… // other methods
}
The problem was not with the recursion. Your function did call itself recursively, it just didn't yield values outside. When you call helper(), you get an iterator as a return value, but you wanted the iterated values of that iterator to be yielded. If you want to yield recursively, you need to yield *
. Try like this:
* inOrderTraversal() {
function* helper(node) {
if (node.left !== null) {
// this line is executed, but helper is not being called
yield * helper(node.left);
}
yield node.value;
if (node.right !== null) {
yield * helper(node.right);
}
}
for (let i of helper(this.root)) {
yield i;
}
}
And while you're at it, you can replace the for
loop with:
yield * helper(this.root)