UNPKG

lilit

Version:

[![Build status][tr-svg]][travis]

797 lines (708 loc) 19.8 kB
// THIS FILE IS AUTO-GENEREATED! DO NOT MODIFY DIRECTLY! // // To edit this file, edit 'async-iter.js' and run 'npm run build:pre'. import { tee, teeN, iterator } from './common.ts'; // OPERATORS export function map<A, B>(f: (x: A) => B) { return function*(xs: Iterable<A>): IterableIterator<B> { for (const x of xs) yield f(x); }; } export function tap<X>(f: (x: X) => any) { return function*(xs: Iterable<X>): IterableIterator<X> { for (const x of xs) { f(x); yield x; } }; } export const inspect = tap; export function forEach<X>(f: (x: X) => any) { return function(xs: Iterable<X>): void { for (const x of xs) f(x); }; } export const subscribe = forEach; export function reduce<X, R>(f: (acc: R, x: X) => R, init: R) { return function(xs: Iterable<X>): R { let res = init; for (const x of xs) { res = f(res, x); } return res; }; } export function scan<X, R>(f: (acc: R, x: X) => R, init: R) { return function*(xs: Iterable<X>): IterableIterator<R> { let res = init; for (const x of xs) { res = f(res, x); yield res; } }; } export const reducutions = scan; export function some<X>(p: (x: X) => boolean) { return function(xs: Iterable<X>): boolean { for (const x of xs) { if (p(x)) return true; } return false; }; } export function every<X>(p: (x: X) => boolean) { return function(xs: Iterable<X>): boolean { for (const x of xs) { if (!p(x)) return false; } return true; }; } export function filter<X>(p: (x: X) => boolean) { return function*(xs: Iterable<X>): IterableIterator<X> { for (const x of xs) { if (p(x)) yield x; } }; } export function partition<X>(p: (x: X) => boolean) { return function(xs: Iterable<X>): [IterableIterator<X>, IterableIterator<X>] { const [xs1, xs2] = tee(xs); return [filter(p)(xs1), filter((x: X) => !p(x))(xs2)]; }; } export function skip<X>(n: number) { return function*(xs: Iterable<X>): IterableIterator<X> { let i = 0; for (const x of xs) { if (++i <= n) continue; yield x; } }; } export function take<X>(n: number) { return function*(xs: Iterable<X>): IterableIterator<X> { let i = 0; for (const x of xs) { if (++i > n) break; yield x; } }; } // TODO: rename? export function partitionAt<X>(n: number) { return function(xs: Iterable<X>): [IterableIterator<X>, IterableIterator<X>] { const [xs1, xs2] = tee(xs); return [take<X>(n)(xs1), skip<X>(n)(xs2)]; }; } export const splitAt = partitionAt; export function skipWhile<X>(f: (x: X) => boolean) { return function*(xs: Iterable<X>): IterableIterator<X> { const it = iterator(xs); let first: X; for (const x of it) { first = x; if (!f(x)) break; } yield first; for (const x of it) yield x; }; } export function takeWhile<X>(f: (x: X) => boolean) { return function*(xs: Iterable<X>): IterableIterator<X> { for (const x of xs) { if (f(x)) yield x; else break; } }; } export function partitionWhile<X>(f: (x: X) => boolean) { return function(xs: Iterable<X>): [IterableIterator<X>, IterableIterator<X>] { const [xs1, xs2] = tee(xs); return [takeWhile<X>(f)(xs1), skipWhile<X>(f)(xs2)]; }; } export function find<X>(p: (x: X) => boolean) { return function(xs: Iterable<X>): X | null { for (const x of xs) { if (p(x)) return x; } return null; }; } export function findIndex<X>(p: (x: X) => boolean) { return function(xs: Iterable<X>): number { let i = 0; for (const x of xs) { if (p(x)) return i; i++; } return -1; }; } export function pluck<X>(key: string | number) { return function*(xs: Iterable<Object>): IterableIterator<X | null> { for (const x of xs) yield x[key]; }; } // like pluck, but accepts an iterable of keys export function select<X>(keys: Array<string | number>) { return function*(xs: Iterable<Object>): IterableIterator<X | null> { for (const x of xs) { let r = x; for (const k of keys) { r = r != null ? r[k] : undefined; } yield r as (X | null); } }; } export function unzip2<X, Y>() { return function(xs: Iterable<[X, Y]>): [IterableIterator<X>, IterableIterator<Y>] { const [xs1, xs2] = tee(xs); return [pluck<X>(0)(xs1), pluck<Y>(1)(xs2)]; }; } export function unzip3<X, Y, Z>() { return function( xs: Iterable<[X, Y, Z]>, ): [IterableIterator<X>, IterableIterator<Y>, IterableIterator<Z>] { const [xs1, xs2, xs3] = teeN(xs, 3); return [pluck<X>(0)(xs1), pluck<Y>(1)(xs2), pluck<Z>(2)(xs3)]; }; } export function unzip(n: number = 2) { return function(xs: Iterable<{}[]>): IterableIterator<{}>[] { const xss = teeN(xs, n); return xss.map((xs, i) => pluck(i)(xs)); }; } export function groupBy<X, K>(f: (x: X) => K) { return function(xs: Iterable<X>): Map<K, X[]> { const res = new Map<K, X[]>(); for (const x of xs) { const key = f(x); if (!res.has(key)) res.set(key, []); res.get(key).push(x); } return res; }; } export function groupByKey<X>(key: string | number) { return groupBy<X, string | number>((x: X) => x[key]); } export function mapKeys<KA, KB, V>(f: (k: KA) => KB) { return function*(xs: Iterable<[KA, V]>): IterableIterator<[KB, V]> { for (const [k, v] of xs) yield [f(k), v]; }; } export function mapValues<VA, VB, K>(f: (v: VA) => VB) { return function*(xs: Iterable<[K, VA]>): IterableIterator<[K, VB]> { for (const [k, v] of xs) yield [k, f(v)]; }; } export function pairwise<X>() { return function*(xs: Iterable<X>): IterableIterator<[X, X]> { const it = iterator(xs); let prev = (it.next()).value; for (const x of it) { yield [prev, x]; prev = x; } }; } export function length() { return function(xs: Iterable<{}>): number { let c = 0; for (const _ of xs) c++; return c; }; } export function min() { return function(xs: Iterable<number>): number { let res = Number.POSITIVE_INFINITY; for (const x of xs) { if (x < res) res = x; } return res; }; } export function max() { return function(xs: Iterable<number>): number { let res = Number.NEGATIVE_INFINITY; for (const x of xs) { if (x > res) res = x; } return res; }; } export function minMax() { return function(xs: Iterable<number>): [number, number] { let min = Number.POSITIVE_INFINITY; let max = Number.NEGATIVE_INFINITY; for (const x of xs) { if (x < min) min = x; if (x > max) max = x; } return [min, max]; }; } export function minBy<X>(cf: (a: X, b: X) => number) { return function(xs: Iterable<X>): X | null { const it = iterator(xs); const { done, value } = it.next(); if (done) return null; let res = value; for (const x of it) if (cf(x, res) < 0) res = x; return res; }; } export function maxBy<X>(cf: (a: X, b: X) => number) { return function(xs: Iterable<X>): X | null { const it = iterator(xs); const { done, value } = it.next(); if (done) return null; let res = value; for (const x of it) if (cf(x, res) > 0) res = x; return res; }; } export function minMaxBy<X>(cf: (a: X, b: X) => number) { return function(xs: Iterable<X>): [X | null, X | null] { const it = iterator(xs); const { done, value } = it.next(); if (done) return [null, null]; let min = value; let max = value; for (const x of it) { if (cf(x, min) < 0) min = x; if (cf(x, max) > 0) max = x; } return [min, max]; }; } export function minByScan<X>(cf: (a: X, b: X) => number) { return function*(xs: Iterable<X>): IterableIterator<X | null> { const it = iterator(xs); const { done, value } = it.next(); if (done) yield null; let res = value; for (const x of it) { if (cf(x, res) < 0) res = x; yield res; } }; } export function maxByScan<X>(cf: (a: X, b: X) => number) { return function*(xs: Iterable<X>): IterableIterator<X | null> { const it = iterator(xs); const { done, value } = it.next(); if (done) yield null; let res = value; for (const x of it) { if (cf(x, res) > 0) res = x; yield res; } }; } export function sum(zero: number = 0) { return function(xs: Iterable<number>): number { let res = zero; for (const x of xs) res += x; return res; }; } export function replaceWhen<X, Y>(pf: (x: X) => boolean, ys: Iterable<Y>) { return function*(xs: Iterable<X>): IterableIterator<X | Y> { for (const [x, y] of zip2(xs, ys)) { if (!pf(x)) yield x; else yield y; } }; } export function grouped<X>(n: number, step: number = n) { return function*(xs: Iterable<X>): IterableIterator<X[]> { let group = []; for (const x of xs) { group.push(x); if (group.length === n) { yield [...group]; for (let i = 0; i < step; i++) group.shift(); } } }; } export function startWith<X>(...as: X[]) { return function*(xs: Iterable<X>): IterableIterator<X> { for (const a of as) yield a; for (const x of xs) yield x; }; } export function endWith<X>(...zs: X[]) { return function*(xs: Iterable<X>): IterableIterator<X> { for (const x of xs) yield x; for (const z of zs) yield z; }; } export function sort<X>(cf: (a: X, b: X) => number) { return function*(xs: Iterable<X>): IterableIterator<X> { let arr = []; for (const x of xs) arr.push(x); for (const x of arr.sort(cf)) yield x; }; } export function sortScan<X>(cf: (a: X, b: X) => number) { return function*(xs: Iterable<X>): IterableIterator<X[]> { let arr = []; for (const x of xs) { arr.push(x); yield [...arr.sort(cf)]; } }; } export function flatMap<A, B>(f: (x: A) => B) { return function*(xss: Iterable<Iterable<A>>): IterableIterator<B> { for (const xs of xss) for (const x of xs) yield f(x); }; } export function distinctUntilChanged<X>(comp: (a: X, b: X) => boolean = (a, b) => a === b) { return function*(xs: Iterable<X>): IterableIterator<X> { const it = iterator(xs); let { done, value: initial } = it.next(); if (done) return; yield initial; for (const x of it) if (!comp(x, initial)) yield (initial = x); }; } export function unique<X>(comp: (a: X, b: X) => boolean = (a, b) => a === b) { return function*(xs: Iterable<X>): IterableIterator<X> { const arr = []; for (const x of xs) arr.push(x); const unq = arr.filter((x, i, self) => self.findIndex(y => comp(x, y)) === i); for (const u of unq) yield u; }; } export function uniqueSorted<X>(comp: (a: X, b: X) => boolean = (a, b) => a === b) { return function*(xs: Iterable<X>): IterableIterator<X> { const arr = []; for (const x of xs) arr.push(x); arr.sort(); for (const x of distinctUntilChanged(comp)(arr)) yield x; }; } // CONSTRUCTORS export function* range(start = 0, end = Number.MAX_SAFE_INTEGER, step = 1): IterableIterator<number> { for (let i = start; end > start ? i < end : i > end; i += step) yield i; } // TODO: rename to `entries`? export function* enumerate<X>(xs: Iterable<X>): IterableIterator<[number, X]> { let i = 0; for (const x of xs) yield [i++, x]; } export function* concat<X>(...xss: Iterable<X>[]): IterableIterator<X> { for (const xs of xss) for (const x of xs) yield x; } export const chain = concat; export function* zip2<X, Y>(xs: Iterable<X>, ys: Iterable<Y>): IterableIterator<[X, Y]> { const xit = iterator(xs); const yit = iterator(ys); while (true) { const [xr, yr] = [xit.next(), yit.next()]; if (xr.done || yr.done) break; yield [xr.value, yr.value]; } } export function* zip3<X, Y, Z>( xs: Iterable<X>, ys: Iterable<Y>, zs: Iterable<Z>, ): IterableIterator<[X, Y, Z]> { const xit = iterator(xs); const yit = iterator(ys); const zit = iterator(zs); while (true) { const [xr, yr, zr] = [xit.next(), yit.next(), zit.next()]; if (xr.done || yr.done || zr.done) break; yield [xr.value, yr.value, zr.value]; } } export function* zip(...xss: Iterable<{}>[]): IterableIterator<{}[]> { const its = xss.map(iterator); while (true) { const rs = its.map(it => it.next()); if (rs.some(r => r.done)) break; yield rs.map(r => r.value); } } // TODO: rename? Is this how regular zip commonly works? export function* zipOuter(...xss: Iterable<{}>[]): IterableIterator<{}[]> { const its = xss.map(iterator); while (true) { const rs = its.map(it => it.next()); if (rs.every(r => r.done)) break; yield rs.map(r => r.value); } } export function* product2<A, B>(as: Iterable<A>, bs: Iterable<B>): IterableIterator<[A, B]> { // if (as === bs) [as, bs] = tee(as); let bs2: Iterable<B>; for (const a of as) { [bs, bs2] = tee(bs); for (const b of bs2) { yield [a, b]; } } } export function* product3<A, B, C>( as: Iterable<A>, bs: Iterable<B>, cs: Iterable<C>, ): IterableIterator<[A, B, C]> { // if (as === bs) [as, bs] = tee(as); // if (as === cs) [as, cs] = tee(as); // if (bs === cs) [bs, cs] = tee(bs); let bs2: Iterable<B>; let cs2: Iterable<C>; for (const a of as) { [bs, bs2] = tee(bs); for (const b of bs2) { [cs, cs2] = tee(cs); for (const c of cs2) { yield [a, b, c]; } } } } // TODO: generalize to n parameters export function* product(xs: Iterable<{}>, ...xss: Iterable<{}>[]): IterableIterator<{}[]> { throw new Error('Not implemented'); } // TODO: other name (look at python itertools?) // TODO: fix implementation export function* combinations2<X>(xs: Iterable<X>): IterableIterator<[X, X]> { let [as, bs] = tee(xs); let bs2: Iterable<X>; let i = 1; for (const a of as) { [bs, bs2] = tee(bs); for (const b of skip<X>(i++)(bs2)) { yield [a, b]; } } } export function* combinations3<X>(xs: Iterable<X>): IterableIterator<[X, X, X]> { throw Error('Not implemented'); // let [as, bs, cs] = teeN(xs, 3); // let bs2: Iterable<X>; // let cs2: Iterable<X>; // let i = 1; // let j = 2; // for (const a of as) { // [bs, bs2] = tee(bs); // for (const b of skip<X>(i++)(bs2)) { // [cs, cs2] = tee(cs); // for (const c of skip<X>(j++)(cs2)) { // yield [a, b, c]; // } // } // } } export function* combinations(xs: Iterable<{}>, r: number = 2): IterableIterator<{}[]> { throw Error('Not implemented'); } export function* combinationsWithReplacement2<X>(xs: Iterable<X>): IterableIterator<[X, X]> { let [as, bs] = tee(xs); let bs2: Iterable<X>; let i = 0; for (const a of as) { [bs, bs2] = tee(bs); for (const b of skip<X>(i++)(bs2)) { yield [a, b]; } } } export function* combinationsWithReplacement3<X>(xs: Iterable<X>): IterableIterator<[X, X, X]> { throw Error('Not implemented'); // let [as, bs, cs] = teeN(xs, 3); // let bs2: Iterable<X>; // let cs2: Iterable<X>; // let i = 0; // let j = 0; // for (const a of as) { // [bs, bs2] = tee(bs); // for (const b of skip<X>(i++)(bs2)) { // [cs, cs2] = tee(cs); // for (const c of skip<X>(j++)(cs2)) { // yield [a, b, c]; // } // } // } } export function* combinationsWithReplacement(xs: Iterable<{}>, r: number = 2): IterableIterator<{}[]> { throw Error('Not implemented'); } export function* permutations2<X>(xs: Iterable<X>): IterableIterator<[X, X]> { throw Error('Not implemented'); } export function* permutations3<X>(xs: Iterable<X>): IterableIterator<[X, X, X]> { throw Error('Not implemented'); } export function* permutations(xs: Iterable<{}>, r: number = 2): IterableIterator<{}[]> { throw Error('Not implemented'); } export function* constantly<X>(value: X): IterableIterator<X> { while (true) yield value; } export function* cycle<X>(xs: Iterable<X>): IterableIterator<X> { let xs2: Iterable<X>; while (true) { [xs, xs2] = tee(xs); for (const x of xs2) yield x; } } export function* repeat<X>(xs: Iterable<X>, n: number): IterableIterator<X> { let xs2: Iterable<X>; for (let i = 0; i < n; i++) { [xs, xs2] = tee(xs); for (const x of xs2) yield x; } } export function* interleave2<X, Y>(xs: Iterable<X>, ys: Iterable<Y>): IterableIterator<X | Y> { const itx = iterator(xs); const ity = iterator(ys); while (true) { const rx = itx.next(); if (rx.done) break; else yield rx.value; const ry = ity.next(); if (ry.done) break; else yield ry.value; } } export function* interleave3<X, Y, Z>( xs: Iterable<X>, ys: Iterable<Y>, zs: Iterable<Z>, ): IterableIterator<X | Y | Z> { const itx = iterator(xs); const ity = iterator(ys); const itz = iterator(zs); while (true) { const rx = itx.next(); if (rx.done) break; else yield rx.value; const ry = ity.next(); if (ry.done) break; else yield ry.value; const rz = itz.next(); if (rz.done) break; else yield rz.value; } } export function* interleave(...xss: Iterable<{}>[]): IterableIterator<{}> { const its = xss.map(iterator); // Throwback to the 90s outerloop: while (true) { for (const it of its) { const { done, value } = it.next(); // Yup, this just happened if (done) break outerloop; else yield value; } } } // https://github.com/Microsoft/TypeScript/issues/17718#issuecomment-402931751 export function pipe<T1>(x: T1): T1; export function pipe<T1, T2>(x: T1, f1: (x: T1) => T2): T2; export function pipe<T1, T2, T3>(x: T1, f1: (x: T1) => T2, f2: (x: T2) => T3): T3; export function pipe<T1, T2, T3, T4>(x: T1, f1: (x: T1) => T2, f2: (x: T2) => T3, f3: (x: T3) => T4): T4; export function pipe<T1, T2, T3, T4, T5>( x: T1, f1: (x: T1) => T2, f2: (x: T2) => T3, f3: (x: T3) => T4, f4: (x: T4) => T5, ): T5; export function pipe<T1, T2, T3, T4, T5, T6>( x: T1, f1: (x: T1) => T2, f2: (x: T2) => T3, f3: (x: T3) => T4, f4: (x: T4) => T5, f5: (x: T5) => T6, ): T6; export function pipe<T1, T2, T3, T4, T5, T6, T7>( x: T1, f1: (x: T1) => T2, f2: (x: T2) => T3, f3: (x: T3) => T4, f4: (x: T4) => T5, f5: (x: T5) => T6, f6: (x: T6) => T7, ): T7; export function pipe<T1, T2, T3, T4, T5, T6, T7, T8>( x: T1, f1: (x: T1) => T2, f2: (x: T2) => T3, f3: (x: T3) => T4, f4: (x: T4) => T5, f5: (x: T5) => T6, f6: (x: T6) => T7, f7: (x: T7) => T8, ): T8; export function pipe<T1, T2, T3, T4, T5, T6, T7, T8, T9>( x: T1, f1: (x: T1) => T2, f2: (x: T2) => T3, f3: (x: T3) => T4, f4: (x: T4) => T5, f5: (x: T5) => T6, f6: (x: T6) => T7, f7: (x: T7) => T8, f8: (x: T8) => T9, ): T9; export function pipe<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>( x: T1, f1: (x: T1) => T2, f2: (x: T2) => T3, f3: (x: T3) => T4, f4: (x: T4) => T5, f5: (x: T5) => T6, f6: (x: T6) => T7, f7: (x: T7) => T8, f8: (x: T8) => T9, f9: (x: T9) => T10, ): T10; export function pipe<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>( x: T1, f1: (x: T1) => T2, f2: (x: T2) => T3, f3: (x: T3) => T4, f4: (x: T4) => T5, f5: (x: T5) => T6, f6: (x: T6) => T7, f7: (x: T7) => T8, f8: (x: T8) => T9, f9: (x: T9) => T10, f10: (x: T10) => T11, ): T11; export function pipe<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>( x: T1, f1: (x: T1) => T2, f2: (x: T2) => T3, f3: (x: T3) => T4, f4: (x: T4) => T5, f5: (x: T5) => T6, f6: (x: T6) => T7, f7: (x: T7) => T8, f8: (x: T8) => T9, f9: (x: T9) => T10, f10: (x: T10) => T11, f11: (x: T11) => T12, ): T12; export function pipe(x: any, ...fs: Function[]): any { let res = x; for (const f of fs) res = f(res); return res; }