I came up with this simple experiment after reading the documentation on generators from MDN:
var nodes = {
type: 'root',
value: [
{ type: 'char', value: 'a' },
{ type: 'char', value: 'b' },
{ type: 'char', value: 'c' },
],
};
function* recursiveGenerator(node) {
if (node.type === 'root') {
node.value.forEach(function (subnode) {
for (var suffix of recursiveGenerator(subnode)) {
yield suffix;
}
});
}
else {
yield node.value;
}
}
for (generated of recursiveGenerator(nodes)) {
console.log(generated);
}
Running it on node.js v0.11.9 with the --harmony
flag set produces the following error:
alix@900X4C:~$ node --version
v0.11.9
alix@900X4C:~$ node --harmony test.js
/home/alix/test.js:14
yield suffix;
^^^^^^
SyntaxError: Unexpected identifier
I also tried using for ... in ...
and the let
keyword instead of var
, but without any success.
I don't understand what yield*
does exactly, but if I use it within the for
loop I get instead:
alix@900X4C:~$ node --harmony test.js
/home/alix/test.js:14
yield* suffix;
^
ReferenceError: yield is not defined
If I replace the yield in the for with console.log()
it outputs a
, b
and c
. What am I doing wrong?
Edit
Here's a minimalistic generator, showing that node.js knows what to do with generators:
function* alpha() {
yield 'a';
yield 'b';
yield 'c';
}
for (var suffix of alpha()) {
console.log(suffix);
}
Output:
alix@900X4C:~$ node --harmony y.js
a
b
c
Solution (thanks @Andrew)
function* recursiveGenerator(node) {
if (node.type === 'root') {
for (var i = 0; i < node.value.length; ++i) {
var subnode = node.value[i];
for (var suffix of recursiveGenerator(subnode)) {
yield suffix;
}
}
}
else {
yield node.value;
}
}
for (generated of recursiveGenerator(nodes)) {
console.log(generated);
}
You've found your solution, but just for the record here is another example a little different that print the types of all nodes in the tree (I added some deepness and vars)
Outputs:
Summarizing the comments: you can't use
yield
inside a regular function, so you can't useyield
withforEach
. Here an example of "generatorized" foreach:UPDATE Also the original problem can be solved quite elegantly using such a helper:
So the generator itself becomes a one-liner!