Random Prototypes
Language Facades
Some random array prototypes I tend to add to most things I do since, so I don’t have to keep reinventing them (handling async in map and foreach is a pain otherwise). I make no claims that these are unique, or that they don’t already exist somewhere on the internets. I can more than likely make claims that there are more efficient ways to do that, but if that was the goal, we would be using Rust instead of Typescript anyhow
Arrays
export {}
declare global {
interface Array<T> {
asyncForEach(callback: (x: T) => void, maxConcurrency?: number): Promise<void>
asyncMap(callback: (x: T) => Promise<U>, maxConcurrency?: number): Promise<U[]>
distinct(): T[]
}
}
Array.prototype.asyncForEach = async function<T>(callback: (x:T) => void, maxConcurrency?: number): Promise<void> {
maxConcurrency = maxConcurrency ?? this.length
let position = 0
while (position < this.length) {
await Promise.all(this.slice(position, position + maxConcurrency).map((x: T) => callback(x)))
position += maxConcurrency
}
}
Array.prototype.asyncMap = async function<T, U>(callback: (x:T) => Promise<U>, maxConcurrency?: number): Promise<U[]> {
maxConcurrency = maxConcurrency ?? this.length
let position = 0
const results: U[] = []
while (position < this.length) {
const batchResults = await Promise.all(this.slice(position, position + maxConcurrency).map((x: T) => callback(x)))
results.push(...batchResults)
position += maxConcurrency
}
}
Array.prototype.distinct = function<T>(this: T[]): T[] {
//INFO: if T is primitive, just use Set directly and assume everything is of the same type
if (typeof this[0] !== 'object') {
return Array.from(new Set(this))
}
//INFO: for non primitives, do a deep compare
const set = new Set(this.map(x => JSON.stringigy(x)))
return Array.from(set).map(x => JSON.parse(x))
}