Skip to content

Instantly share code, notes, and snippets.

@conartist6
Created November 7, 2022 22:33
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 conartist6/06fa9081af487c7867c1a952d786a84a to your computer and use it in GitHub Desktop.
Save conartist6/06fa9081af487c7867c1a952d786a84a to your computer and use it in GitHub Desktop.
splitWhen for trusted destructuring
export class Coroutine {
constructor(generator) {
this.generator = generator[Symbol.iterator]();
this.current = this.generator?.next();
}
get value() {
return this.current.value;
}
get done() {
return this.current.done;
}
advance(value) {
if (this.current.done) {
throw new Error('Cannot advance a coroutine that is done');
}
this.current = this.generator.next(value);
return this;
}
return(value) {
this.current = this.generator.return(value);
}
}
export function* empty() {}
// Note: This will break if the caller mixes destructuring and non-destructuring.
// e.g. [[...a], [b], [...c]] = splitWhen(...)
export function* splitWhen(condition, iter) {
const co = new Coroutine(iter);
function* part() {
if (!co.done && condition(co.value)) {
co.advance();
}
while (!co.done && !condition(co.value)) {
yield co.value;
co.advance();
}
}
if (!co.done && condition(co.value)) {
yield empty();
}
do {
yield part();
} while (!co.done);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment