I've got two iterators that may or may not be iterable. If they were both guaranteed to be iterable, I could probably use an array and call .values() to get another iterable iterator:
[...iter1, ...iter2].values(); // simple :)
However, I'm struggling to find a way to chain them together if they aren't iterable. I considered using a generator function, but that would return a generator and not an iterator. Ideally, the returned iterator should also not be iterable.
This returns an iterable iterator and only works for iterable iterators:
const iter1 = [1, 2, 3].values();
const iter2 = [4, 5, 6].values();
console.log([...[...iter1, ...iter2].values()]);
This works for iterators that aren't iterable but instead returns a generator:
const iter1 = [1, 2, 3].values();
const iter2 = [4, 5, 6].values();
console.log([...(function* () {
let item;
while (!(item = iter1.next()).done) yield item.value;
while (!(item = iter2.next()).done) yield item.value;
})()]);
So how would I take two iterators and chain them together to create a new iterator?
Maybe an XY problem; I'm concerned about iterability since TypeScript has separate interfaces: Iterator and IterableIterator. Is it implying that you can create an iterator that isn't iterable, or are all iterators in JavaScript iterable, and TypeScript is just being weird?
I'll post the obvious answer that despite being old-fashioned and baroque, seems to fit the requirements:
class ConsIterable{
constructor(...iterators){
this.iterators = iterators;
this.current = 0;
}
next(){
let result;
do{
result = this.iterators[this.current].next();
if(result.done){
this.current++;
}
}while(result.done && this.current < this.iterators.length);
return result;
}
}
const iter1 = [1, 2, 3].values();
const iter2 = [4, 5, 6].values();
const chained_iterable = new ConsIterable(iter1, iter2);
let nxt;
do{
nxt = chained_iterable.next();
console.log(nxt);
}while(!nxt.done)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With