Skip to content

Instantly share code, notes, and snippets.

@rgoupil
Last active May 10, 2022 14:35
Show Gist options
  • Save rgoupil/156cfb467881223c0f4febd38a58b8a1 to your computer and use it in GitHub Desktop.
Save rgoupil/156cfb467881223c0f4febd38a58b8a1 to your computer and use it in GitHub Desktop.
Utility functions for Array and Generator - TS target must be >= ES2018
declare global {
interface Array<T> {
toArray(): Array<T>;
/**
* Same as Array.prototype.map() but can take an async transform function while still iterating sequentially
*/
mapAsync<R>(fn: (item: T, i: number, array: ThisType<T>) => Promise<R>): Promise<Array<R>>;
}
}
Array.prototype.toArray = function() {
return Array.from(this);
}
Array.prototype.mapAsync = async function<R>(fn) {
const clone: Array<R> = [];
for (let i = 0; i < this.length; i++) {
clone.push(await fn(this[i], i, this));
}
return clone;
};
declare global {
interface AsyncGenerator<T> {
toArray(): Promise<Array<T>>;
map<R>(fn: (x: T, i: number) => R | Promise<R>): AsyncGenerator<R>;
}
interface Generator<T> {
toArray(): Array<T>;
map<R>(fn: (x: T, i: number) => R): Generator<R>;
}
}
const asyncGeneratorFunction: AsyncGeneratorFunction = Object.getPrototypeOf(async function*(){});
asyncGeneratorFunction.prototype.toArray = function() {
const arr: Array<T> = [];
for await (const it of iterable) {
arr.push(it);
}
return arr;
};
asyncGeneratorFunction.prototype.map = function(fn) {
let i = 0;
for await (const it of iterable) {
yield fn(it, i++);
}
};
const generatorFunction: GeneratorFunction = Object.getPrototypeOf(function*(){});
generatorFunction.prototype.toArray = function() {
const arr: Array<T> = [];
for (const it of iterable) {
arr.push(it);
}
return arr;
};
generatorFunction.prototype.map = function(fn) {
let i = 0;
for (const it of iterable) {
yield fn(it, i++);
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment