functional/iterables.ts

73 lines
1.5 KiB
TypeScript
Raw Normal View History

2020-05-11 22:34:57 +00:00
/**
* Index getter
*/
export function at<T>(idx: number): (array: ReadonlyArray<T>) => T | undefined {
if (idx < 0) {
return (array) => array[array.length + idx];
} else {
return (array) => array[idx];
}
}
/**
* Array first item getter
*/
export const first: <T extends ReadonlyArray<any>>(
array: T,
) => T[0] | undefined = at(0);
/**
* Array second item getter
*/
export const second: <T extends ReadonlyArray<any>>(
array: T,
) => T[1] | undefined = at(1);
/**
* Array third item getter
*/
export const third: <T extends ReadonlyArray<any>>(
array: T,
) => T[2] | undefined = at(2);
/**
* Array last item getter
*/
export const last: <T>(array: ReadonlyArray<T>) => T | undefined = at(-1);
/**
* Applies map and filter on an array, using a single function
*/
export function fmap<A, T extends A>(
m?: undefined,
f?: (val: A) => val is T,
): (array: A[]) => T[];
export function fmap<A>(
m?: undefined,
f?: (val: A) => boolean,
): (array: A[]) => A[];
export function fmap<A, B, T extends B>(
m: (val: A) => B,
f?: (val: B) => val is T,
): (array: A[]) => T[];
export function fmap<A, B>(
m: (val: A) => B,
f?: (val: B) => boolean,
): (array: A[]) => B[];
export function fmap<A, B>(
m?: (val: A) => B,
f?: (val: A | B) => boolean,
): (array: A[]) => (A | B)[] {
return (array) => {
if (m && f) {
return array.map(m).filter(f);
} else if (m) {
return array.map(m);
} else if (f) {
return array.filter(f);
} else {
return array.slice();
}
};
}