Last active
September 4, 2022 02:45
-
-
Save MikuroXina/1273bf7c7dab757cad9de183707beff8 to your computer and use it in GitHub Desktop.
Utility generator collection.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| function* empty<T>(): Generator<T, void> {} | |
| function* once<T>(elem: T): Generator<T, void> { | |
| yield elem; | |
| } | |
| function* onceWith<T>(fn: () => T): Generator<T, void> { | |
| yield fn(); | |
| } | |
| function* repeat<T>(elem: T): Generator<T, never> { | |
| while (true) { | |
| yield elem; | |
| } | |
| } | |
| function* repeatWith<T>(fn: () => T): Generator<T, never> { | |
| while (true) { | |
| yield fn(); | |
| } | |
| } | |
| function* successors<T>(first: T, succ: (t: T) => T): Generator<T, never> { | |
| while (true) { | |
| yield first; | |
| first = succ(first); | |
| } | |
| } | |
| function* range(start: number, end: number, step: number = 1): Generator<number, void> { | |
| while (start < end) { | |
| yield start; | |
| start += step; | |
| } | |
| } | |
| function* digits(num: number, radix: number): Generator<number, void> { | |
| if (!Number.isInteger(num)) { | |
| throw new Error("num must be an integer"); | |
| } | |
| if (!Number.isInteger(radix) || radix <= 0) { | |
| throw new Error("radix must be a positive integer"); | |
| } | |
| while (num != 0) { | |
| yield num % radix; | |
| num /= radix; | |
| } | |
| } | |
| function* zip<A, B>(a: Iterable<A>, b: Iterable<B>): Generator<[A, B], void> { | |
| const aIt = a[Symbol.iterator](); | |
| const bIt = b[Symbol.iterator](); | |
| while (true) { | |
| const aNext = aIt.next(); | |
| const bNext = bIt.next(); | |
| if (aNext.done || bNext.done) { | |
| break; | |
| } | |
| yield [aNext.value, bNext.value]; | |
| } | |
| } | |
| function* chain<T>(aIter: Iterable<T>, bIter: Iterable<T>): Generator<T> { | |
| yield* aIter; | |
| yield* bIter; | |
| } | |
| function* cycle<T>(iter: Iterable<T>): Generator<T, void> { | |
| if (iter[Symbol.iterator]().next().done) { | |
| return; | |
| } | |
| while (true) { | |
| yield* iter; | |
| } | |
| } | |
| function* enumerate<T>(iter: Iterable<T>): Generator<[number, T], void> { | |
| let i = 0; | |
| for (const elem : iter) { | |
| yield [i, elem]; | |
| i += 1; | |
| } | |
| } | |
| function* skipWhile<T>(iter: Iterable<T>, pred: (t: T) => boolean): Generator<T, void> { | |
| let skipping = true; | |
| for (const elem of iter) { | |
| if (skipping && !pred(elem)) { | |
| skipping = false; | |
| } | |
| if (!skipping) { | |
| yield elem; | |
| } | |
| } | |
| } | |
| function* takeWhile<T>(iter: Iterable<T>, pred: (t: T) => boolean): Generator<T, void> { | |
| for (const elem of iter) { | |
| if (!pred(elem)) { | |
| break; | |
| } | |
| yield elem; | |
| } | |
| } | |
| function* filter<T, U>(iter: Iterable<T>, pred: (t: T) => boolean): Generator<T, void> { | |
| for (const elem of iter) { | |
| if (pred(elem)) { | |
| yield elem; | |
| } | |
| } | |
| } | |
| function* flatten<T>(iter: Iterable<Iterable<T>>): Generator<T, void> { | |
| for (const elemIter of iter) { | |
| for (const elem of elemIter) { | |
| yield elem; | |
| } | |
| } | |
| } | |
| function* map<T, U>(iter: Iterable<T>, fn: (t: T) => U): Generator<U, void> { | |
| for (const elem of iter) { | |
| yield fn(elem); | |
| } | |
| } | |
| function* skip<T>(iter: Iterable<T>, n: number): Generator<T, void> { | |
| if (!Number.isInteger(n) || n < 0) { | |
| throw new Error("n must be a non-negative integer"); | |
| } | |
| for (const elem of iter) { | |
| if (n <= 0) { | |
| yield elem; | |
| } | |
| n -= 1; | |
| } | |
| } | |
| function* take<T>(iter: Iterable<T>, n: number): Generator<T, void> { | |
| if (!Number.isInteger(n) || n < 0) { | |
| throw new Error("n must be a non-negative integer"); | |
| } | |
| for (const elem of iter) { | |
| if (n <= 0) { | |
| break; | |
| } | |
| yield elem; | |
| n -= 1; | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment