pragmatic-fp-ts
Version:
Opinionated functional programming library with easy use in mind
37 lines (31 loc) • 1.4 kB
text/typescript
import { Dictionary, getValue } from "./main.ts";
type ArrayMappable<A, B> = (value: A, idx: number) => B;
type DictMappable<A, B> = (value: A, key: string) => B;
const mapArrayIndexed = <A, B>(fn: ArrayMappable<A, B>, coll: A[]): B[] => coll?.map(fn);
const mapObjIndexed = <A, B>(fn: DictMappable<A, B>, dict: Dictionary<A>): Dictionary<B> =>
dict &&
Object.keys(dict).reduce((accum: Dictionary<B>, key) => {
try {
accum[key] = fn(dict[key], key);
return accum;
} catch (err) {
throw new Error(`Error mapping functor over object key ${key}: ${(err as Error).message}`);
}
}, {});
export function mapIndexed<A, B>(fn: ArrayMappable<A, B>, coll: A[]): B[];
export function mapIndexed<A, B>(fn: ArrayMappable<A, B>): (coll: A[]) => B[];
export function mapIndexed<A, B>(fn: DictMappable<A, B>, coll: Dictionary<A>): Dictionary<B>;
export function mapIndexed<A, B>(fn: DictMappable<A, B>): (coll: Dictionary<A>) => Dictionary<B>;
export function mapIndexed<A, B>(
fn: ArrayMappable<A, B> | DictMappable<A, B>,
coll?: A[] | Dictionary<A>
): any {
if (arguments.length === 1) {
return (_coll: A[] | Dictionary<A>) => mapIndexed(fn as any, _coll as any);
} else {
const input = getValue(coll);
return input instanceof Array
? mapArrayIndexed(fn as ArrayMappable<A, B>, input)
: mapObjIndexed(fn as DictMappable<A, B>, input);
}
}