Skip to content

Instantly share code, notes, and snippets.

@XoseLluis
Created February 20, 2022 12:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save XoseLluis/781211821c522a1f430106199ed9731a to your computer and use it in GitHub Desktop.
Save XoseLluis/781211821c522a1f430106199ed9731a to your computer and use it in GitHub Desktop.
itertools.tee for JavaScript
function tee(iterable, num){
let internalIterator = iterable[Symbol.iterator]();
let buffer = [];
//it's very interesting that a generator function can capture the outer variables in a closure, though
//in the end what is being generated by the compiler is an object with a next() method, not a function having access to the activation object
function* generatorFn(){
let pos = 0;
let finished = false;
while (!finished){
if (pos < buffer.length){
yield buffer[pos];
}
else{
it = internalIterator.next();
if (it.done){
finished = true;
}
else{
buffer.push(it.value);
yield it.value;
}
}
pos++;
}
};
let generatorObjs = []
for (let i=0; i<num; i++){
generatorObjs.push(generatorFn());
}
return generatorObjs;
}
//let items = ["a", "b", "c"];
let generatorObj = (function*(){
yield "a";
yield "b";
yield "c";
})()
/*can be iterated only once
for (it of generatorObj){
console.log(it);
}
//here the iterator is already complete, so nothing to iterate
for (it of generatorObj){
console.log(it);
}
*/
let [iter1, iter2, iter3, iter4] = tee(generatorObj, 4);
console.log(iter1.next().value);
console.log(iter2.next().value);
console.log(iter2.next().value);
console.log(iter2.next().value);
console.log(iter2.next().value);
console.log(iter1.next().value);
console.log(iter1.next().value);
console.log(iter1.next().value);
for (it of iter3){
console.log(it);
}
for (it of iter4){
console.log(it);
}
/*
a
a
b
c
undefined
b
c
undefined
a
b
c
a
b
c
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment