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