export function last(seq: Iterator): T | undefined { let result; let iter = seq.next(); while (!iter.done) { result = iter.value; iter = seq.next(); } return result; } export function first(seq: Iterator): T | undefined { let iter = seq.next(); return iter.done ? undefined : iter.value; } export function* skip(seq: Iterator, n: number): IterableIterator { let i = 0; let iter = seq.next(); while (!iter.done) { if (i >= n) { yield iter.value; } iter = seq.next(); i++; } } export function* take(seq: Iterator, n: number): IterableIterator { let i = 0; let iter = seq.next(); while (!iter.done) { if (i >= n) { break; } yield iter.value; iter = seq.next(); i++; } } export function* map(src: IterableIterator, f: (x: F) => T) { for (let x of src) { yield f(x); } } export function reduce(src: IterableIterator, r: (c: T, x: F) => T, s: T): T { let result = s; for (let x of src) { result = r(result, x); } return result; } export function* filter(src: IterableIterator, f: (x: T) => boolean) { for (let x of src) { if (f(x)) { yield x; } } } export function asArray(src: IterableIterator): T[] { let result = []; for (const e of src) { result.push(e); } return result; } export function* reverse(src: IterableIterator): IterableIterator { const arr = asArray(src); const reversed = arr.reverse(); for (const e of reversed) { yield e; } } export function* asIter(a: T[]) { for (const v of a) { yield v; } } export function* chunks(src: IterableIterator, chunkSize: number): IterableIterator> { let chunk = []; for (const v of src) { chunk.push(v); if (chunk.length === chunkSize) { yield asIter(chunk); chunk = []; } } if (chunk.length) { yield asIter(chunk); } }