How to implement recursive traversal inside iterator generator in javascript?

Let's say I have a tree, something like the following, in javascript:

let rootNode = {name:'', children:[
                   {name:'0', children:[
                       {name:'00', children:[]},
                       {name:'01', children:[
                           {name:'010', children:[]},
                       ]},
                       {name:'02', children:[]},
                   ]},
                   {name:'1', children:[
                       {name:'10', children:[]},
                   ]},
               ]};

And I want to do a pre-order bypass on it, I could do it like this:

function preOrderTraversalRecursive(rootNode, visitNodeCallback) {
    function recurse(node) {
        visitNodeCallback(node);
        for (let childNode of node.children)
          recurse(childNode);
    }
    recurse(rootNode);
};
console.log("Pre-order traveral, recursive:");
preOrderTraversalRecursive(rootNode, function visitNodeCallback(node) {
    console.log("  '"+node.name+"'");
});

which gives the expected result:

  Pre-order traveral, recursive:
    ''
    '0'
    '00'
    '01'
    '010'
    '02'
    '1'
    '10'

Now let me say that I want to do the same thing as the ES6 generator. I thought it would look like this:

function *preOrderGeneratorIteratorRecursive(rootNode) {
    function recurse(node) {
        yield node;
        for (let childNode of node.children)
            recurse(childNode);
    }
    recurse(rootNode);
};
console.log("Pre-order generator iterator, recursive:");
for (let node of preOrderGeneratorIteratorRecursive(rootNode)) {
    console.log("  '"+node.name+"'");
}

But, apparently, it is illegal: Uncaught SyntaxError: Unexpected strict mode reserved wordon yield.

Unsatisfactory! Is there any syntax that I am missing? What is the cleanest way to make a generator expressing this algorithm? Perhaps using some helper library?

, , : (1) , ; (2) , node. . , , node.children - , , .

function *preOrderTraversalIteratorGeneratorExplicitStackCheating(rootNode) {
  let stack = [rootNode];
  while (stack.length > 0) {
    let node = stack.pop();
    yield node;
    for (let i = node.children.length-1; i >= 0; --i) // backwards
      stack.push(node.children[i]);
  }
} // preOrderIteratorGeneratorExplicitStackCheating
console.log("Pre-order traveral of tree with explicit stack, cheating:");
for (let node of preOrderTraversalIteratorGeneratorExplicitStackCheating(rootNode)) {
  console.log("  '"+node.name+"'");
}

: , . , , .

+4
2

yield*. , , . (, .)

, :

function *pointlessGenerator() {
    yield* [1, 2, 3, 4];
} 

1, 2, 3 4, yield* . , .

recurse , yield*:

function *preOrderGeneratorIteratorRecursive(rootNode) {
    function *recurse(node) {
        yield node;
        for (let childNode of node.children)
            yield* recurse(childNode);
    }
    yield* recurse(rootNode);
};
console.log("Pre-order generator iterator, recursive:");
for (let node of preOrderGeneratorIteratorRecursive(rootNode)) {
    console.log("  '"+node.name+"'");
}
+2

, recurse, yield, . .

function preOrderGeneratorIteratorRecursive(rootNode) {
    function* recurse(node) {
        yield node;
        for (let childNode of node.children)
            yield* recurse(childNode);
    }
    return recurse(rootNode);
}

function* preOrderGenerator(node) {
    yield node;
    for (let childNode of node.children)
        yield* preOrderGenerator(childNode);
}
0

Source: https://habr.com/ru/post/1669277/


All Articles