I have a generator called generateNumbers
in JavaScript and another generator generateLargerNumbers
which takes each value generated by generateNumbers
and applies a function addOne
to it, as such:
function addOne(value) {
return value + 1
}
function* generateNumbers() {
yield 1
yield 2
yield 3
}
function* generateLargerNumbers() {
for (const number of generateNumbers()) {
yield addOne(number)
}
}
Is there any terser way to do this without building an array out of the generated values? I'm thinking something like:
function* generateLargerNumbers() {
yield* generateNumbers().map(addOne) // obviously doesn't work
}
There isn't a built-in way to map over
Generator
objects, but you could roll your own function:Now you can do:
If you need to actually pass values to your generator then you can't do it with for...of, you have to pass each value through
How about composing an iterator object, instead of using the nested generators?
higher-order generators
You can choose to manipulate the generator functions themselves
higher-order iterators
Or you can choose to manipulate iterators
recommendation
In most cases, I think it's more practical to manipulate the iterator because of it's well-defined (albeit kludgy) interface. It allows you to do something like
Whereas the other approach is
Both have a use-case, but I find the former much nicer than the latter
persistent iterators
JavaScript's stateful iterators annoy me – each subsequent call to
.next
alters the internal state irreversibly.But! there's nothing stopping you from making your own iterators tho and then creating an adapter to plug into JavaScript's stack-safe generator mechanism
If this interests you, you might like some of the other accompanying examples found here: Loop to a filesystem structure in my object to get all the files
The only gain isn't that we can reuse a persistent iterator, it's that with this implementation, subsequent reads are even faster than the first because of memoisation – score: JavaScript 0, Persistent Iterators 2