function from<T>(iterable: Iterable<T>): IteratorWrapper<T> { return new IteratorWrapper(iterable); } function* map<T, U>(iter: Iterator<T>, f: (value: T) => U): Generator<U> { for (let x of iterableFromIterator(iter)) { yield f(x); } } function* filter<T>(iter: Iterator<T>, f: (value: T) => boolean): Generator<T> { for (let x of iterableFromIterator(iter)) { if (f(x)) yield x; } } function* take<T>(iter: Iterator<T>, n: number): Generator<T> { let i = 0; for (let x of iterableFromIterator(iter)) { if (i++ < n) yield x; else break; } } function* skip<T>(iter: Iterator<T>, n: number): Generator<T> { let i = 0; for (let x of iterableFromIterator(iter)) { if (i++ >= n) yield x; } } function iterableFromIterator<T>(iter: Iterator<T>): Iterable<T> { return { [Symbol.iterator]() { return iter; } }; } class IteratorWrapper<T> implements Iterable<T> { private iter: Iterator<T>; constructor(iterable: Iterable<T>) { this.iter = iterable[Symbol.iterator](); } [Symbol.iterator](): Iterator<T> { return this.iter; } map<U>(f: (value: T) => U): IteratorWrapper<U> { return from(map(this.iter, f)); } filter(f: (value: T) => boolean): IteratorWrapper<T> { return from(filter(this.iter, f)); } take(n: number): IteratorWrapper<T> { return from(take(this.iter, n)); } skip(n: number): IteratorWrapper<T> { return from(skip(this.iter, n)); } first(): T | undefined { const { value, done } = this.iter.next(); return done ? undefined : value; } last(): T | undefined { let lastValue: T | undefined = undefined; for (let x of iterableFromIterator(this.iter)) { lastValue = x; } return lastValue; } sum(fn: (arg: T) => number): number { let total = 0; for (let x of iterableFromIterator(this.iter)) { total += fn(x); } return total; } min(fn: (arg: T) => number): number | undefined { let minValue: number | undefined = undefined; for (let x of iterableFromIterator(this.iter)) { const val = fn(x); if (minValue === undefined || val < minValue) { minValue = val; } } return minValue; } max(fn: (arg: T) => number): number | undefined { let maxValue: number | undefined = undefined; for (let x of iterableFromIterator(this.iter)) { const val = fn(x); if (maxValue === undefined || val > maxValue) { maxValue = val; } } return maxValue; } toArray(): T[] { return [...iterableFromIterator(this.iter)]; } }
Example use:
const numbers = [1, 2, 3, 4, 5]; const result = from(numbers) .map(x => x * 2) .filter(x => x > 5) .take(2) .toArray(); console.log(result); // [6, 8] const values = from([1, 2, 3, 4, 5]); console.log(values.skip(2).toArray()); // [3, 4, 5] console.log(from([1, 2, 3]).first()); // 1 console.log(from([1, 2, 3]).last()); // 3 console.log(from([1, 2, 3]).sum(x => x)); // 6 console.log(from([1, 2, 3]).min(x => x)); // 1 console.log(from([1, 2, 3]).max(x => x)); // 3
Generated javascript
"use strict"; function from(iterable) { return new IteratorWrapper(iterable); } function* map(iter, f) { for (let x of iterableFromIterator(iter)) { yield f(x); } } function* filter(iter, f) { for (let x of iterableFromIterator(iter)) { if (f(x)) yield x; } } function* take(iter, n) { let i = 0; for (let x of iterableFromIterator(iter)) { if (i++ < n) yield x; else break; } } function* skip(iter, n) { let i = 0; for (let x of iterableFromIterator(iter)) { if (i++ >= n) yield x; } } function iterableFromIterator(iter) { return { [Symbol.iterator]() { return iter; } }; } class IteratorWrapper { constructor(iterable) { this.iter = iterable[Symbol.iterator](); } [Symbol.iterator]() { return this.iter; } map(f) { return from(map(this.iter, f)); } filter(f) { return from(filter(this.iter, f)); } take(n) { return from(take(this.iter, n)); } skip(n) { return from(skip(this.iter, n)); } first() { const { value, done } = this.iter.next(); return done ? undefined : value; } last() { let lastValue = undefined; for (let x of iterableFromIterator(this.iter)) { lastValue = x; } return lastValue; } sum(fn) { let total = 0; for (let x of iterableFromIterator(this.iter)) { total += fn(x); } return total; } min(fn) { let minValue = undefined; for (let x of iterableFromIterator(this.iter)) { const val = fn(x); if (minValue === undefined || val < minValue) { minValue = val; } } return minValue; } max(fn) { let maxValue = undefined; for (let x of iterableFromIterator(this.iter)) { const val = fn(x); if (maxValue === undefined || val > maxValue) { maxValue = val; } } return maxValue; } toArray() { return [...iterableFromIterator(this.iter)]; } } const numbers = [1, 2, 3, 4, 5]; const result = from(numbers) .map(x => x * 2) .filter(x => x > 5) .take(2) .toArray(); console.log(result); // [6, 8] const values = from([1, 2, 3, 4, 5]); console.log(values.skip(2).toArray()); // [3, 4, 5] console.log(from([1, 2, 3]).first()); // 1 console.log(from([1, 2, 3]).last()); // 3 console.log(from([1, 2, 3]).sum(x => x)); // 6 console.log(from([1, 2, 3]).min(x => x)); // 1
946500cookie-checkTypescript Generic IteratorWrapper