/** * @public * @deprecated use a simple Arrays */ export abstract class FunctionalVector { abstract get length(): number; abstract get(index: number): T; // Implement "iterator protocol" *iterator(): Generator { for (let i = 0; i < this.length; i++) { yield this.get(i); } } set(index: number, value: T): void { throw 'unsupported operation'; } add(value: T): void { throw 'unsupported operation'; } push(...vals: T[]): number { for (const v of vals) { this.add(v); } return this.length; } // Implement "iterable protocol" [Symbol.iterator]() { return this.iterator(); } forEach(iterator: (row: T, index: number, array: T[]) => void): void { return vectorator(this).forEach(iterator); } map(transform: (item: T, index: number, array: T[]) => V): V[] { return vectorator(this).map(transform); } filter(predicate: (item: T, index: number, array: T[]) => boolean): T[] { return vectorator(this).filter(predicate); } at(index: number): T | undefined { return this.get(index); } toArray(): T[] { const arr = new Array(this.length); for (let i = 0; i < this.length; i++) { arr[i] = this.get(i); } return arr; } join(separator?: string | undefined): string { return this.toArray().join(separator); } toJSON(): any { return this.toArray(); } //-------------------------- // Method not implemented //-------------------------- [n: number]: T; pop(): T | undefined { throw new Error('Method not implemented.'); } concat(...items: Array>): T[]; concat(...items: Array>): T[] { throw new Error('Method not implemented.'); } reverse(): T[] { throw new Error('Method not implemented.'); } shift(): T | undefined { throw new Error('Method not implemented.'); } sort(compareFn?: ((a: T, b: T) => number) | undefined): this { throw new Error('Method not implemented.'); } splice(start: number, deleteCount?: number | undefined): T[]; splice(start: number, deleteCount: number, ...items: T[]): T[] { throw new Error('Method not implemented.'); } unshift(...items: T[]): number { throw new Error('Method not implemented.'); } fill(value: T, start?: number | undefined, end?: number | undefined): this { throw new Error('Method not implemented.'); } copyWithin(target: number, start: number, end?: number | undefined): this { throw new Error('Method not implemented.'); } // Object not implemented [Symbol.unscopables] = {}; //-------------------------------------------------------------------------------- // Delegated Array function -- these will not be efficient :grimmice: //-------------------------------------------------------------------------------- slice(start?: number | undefined, end?: number | undefined): T[] { return this.toArray().slice(start, end); } indexOf(searchElement: T, fromIndex?: number | undefined): number { return this.toArray().indexOf(searchElement, fromIndex); } lastIndexOf(searchElement: T, fromIndex?: number | undefined): number { return this.toArray().lastIndexOf(searchElement, fromIndex); } every(predicate: (value: T, index: number, array: T[]) => value is S, thisArg?: any): this is S[]; every(predicate: (value: T, index: number, array: T[]) => unknown, thisArg?: any): boolean; every(predicate: any, thisArg?: unknown): boolean { return this.toArray().every(predicate, thisArg); } some(predicate: (value: T, index: number, array: T[]) => unknown, thisArg?: any): boolean { return this.toArray().some(predicate, thisArg); } reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T; reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T; reduce(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U; reduce(callbackfn: unknown, initialValue?: unknown): T { throw new Error('Method not implemented.'); } reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T; reduceRight( callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T ): T; reduceRight( callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U ): U; reduceRight(callbackfn: unknown, initialValue?: unknown): T { throw new Error('Method not implemented.'); } find( predicate: (this: void, value: T, index: number, obj: T[]) => value is S, thisArg?: any ): S | undefined; find(predicate: (value: T, index: number, obj: T[]) => unknown, thisArg?: any): T | undefined { return this.toArray().find(predicate, thisArg); } findIndex(predicate: (value: T, index: number, obj: T[]) => unknown, thisArg?: any): number { return this.toArray().findIndex(predicate, thisArg); } entries(): ArrayIterator<[number, T]> { return this.toArray().entries(); } keys(): ArrayIterator { return this.toArray().keys(); } values(): ArrayIterator { return this.toArray().values(); } includes(searchElement: T, fromIndex?: number | undefined): boolean { return this.toArray().includes(searchElement, fromIndex); } flatMap( callback: (this: This, value: T, index: number, array: T[]) => U | readonly U[], thisArg?: This | undefined ): U[] { return this.toArray().flatMap(callback, thisArg); } flat(this: A, depth?: D | undefined): Array> { throw new Error('Method not implemented.'); } } const emptyarray: any[] = []; /** * Use functional programming with your vector * * @deprecated use a simple Arrays */ export function vectorator(vector: FunctionalVector) { return { *[Symbol.iterator]() { for (let i = 0; i < vector.length; i++) { yield vector.get(i); } }, forEach(iterator: (row: T, index: number, array: T[]) => void): void { for (let i = 0; i < vector.length; i++) { iterator(vector.get(i), i, emptyarray); } }, map(transform: (item: T, index: number, array: T[]) => V): V[] { const result: V[] = []; for (let i = 0; i < vector.length; i++) { result.push(transform(vector.get(i), i, emptyarray)); } return result; }, /** Add a predicate where you return true if it should *keep* the value */ filter(predicate: (item: T, index: number, array: T[]) => boolean): T[] { const result: T[] = []; let count = 0; for (const val of this) { if (predicate(val, count++, emptyarray)) { result.push(val); } } return result; }, }; }