import { PromiseReturnType,
CheckPromiseType, CheckIterableType,
CheckPromiseIterableType, Curry2, Curry1 } from "../types";
import { exec, curry } from "../utils";
/**
* @namespace array
*/
/**
* @memberof array
* @typedef
*/
export type EachArrayCallbackType<T, U, R extends Array<T | Promise<T>> = T[]> =
(value: T, key: number, iterator: R) => U;
/**
* @memberof array
* @typedef
*/
export type ReduceArrayCallbackType<T, U, R extends Array<U | Promise<U>> = U[]> =
(previousValue: T, currentValue: U, currentIndex: number, arr: R) => T;
/**
* @memberof array
* @typedef
*/
export type ArrayPromiseReturnType<T extends any[]> = CheckPromiseType<
CheckIterableType<T>,
PromiseReturnType<Array<CheckPromiseIterableType<T>>>,
Array<CheckPromiseIterableType<T>>>;
/**
* @memberof array
*/
export function eachArrayF<T>(f: EachArrayCallbackType<T, void>, arr: T[]): T[] {
arr.forEach(f);
return arr;
}
/**
* @memberof array
* @function
*/
export const eachArray:
(<T = any>(f: EachArrayCallbackType<T, void>) => <U extends T>(arr: U[]) => U[]) &
(<T = any>(f: EachArrayCallbackType<T, void>, arr: T[]) => T[]) =
/*#__PURE__*/curry(eachArrayF);
/**
* @memberof array
*/
export function mapArrayF<T, U>(f: EachArrayCallbackType<T, U>, arr: T[]): U[] {
return arr.map(f);
}
/**
* @memberof array
* @function
*/
export const mapArray:
(<T = any, U = any>(f: EachArrayCallbackType<T, U>) => <A extends T, B extends U>(arr: A[]) => B[]) &
(<T = any, U = any>(f: EachArrayCallbackType<T, U>, arr: T[]) => U[]) =
/*#__PURE__*/curry(mapArrayF);
/**
* @memberof array
*/
export function reduceArrayF<T, U>(
callbackFn: ReduceArrayCallbackType<T, U>,
initial: T,
arr: U[]): T {
return arr.reduce(callbackFn, initial);
}
/**
* @memberof array
* @function
*/
export const reduceArray:
(<T, U>(callbackFn: ReduceArrayCallbackType<T, U>) => Curry2<T, U[], T>) &
(<T, U>(callbackFn: ReduceArrayCallbackType<T, U>, initial: T) => Curry1<U[], T>) &
(<T, U>(callbackFn: ReduceArrayCallbackType<T, U>, initial: T, arr: U[]) => T) =
/*#__PURE__*/curry(reduceArrayF);
/**
* @memberof array
*/
export function filterArrayF<T>(f: EachArrayCallbackType<T, boolean>, arr: T[]): T[] {
return arr.filter(f);
}
/**
* @memberof array
* @function
*/
export const filterArray:
(<T = any>(f: EachArrayCallbackType<T, boolean>) => Curry1<T[], T[]>) &
(<T = any>(f: EachArrayCallbackType<T, boolean>, arr: T[]) => T[]) =
/*#__PURE__*/ curry(filterArrayF);
/**
* @memberof array
*/
export function headArray<T>(iterator: T[]): T {
return iterator[0];
}
/**
* @memberof array
*/
export function tailArray<T>(iterator: T[]): T {
return iterator[iterator.length - 1];
}
export function takeArrayF<T extends any[]>(length: number, arr: T):
ArrayPromiseReturnType<T>;
/**
* @memberof array
*/
export function takeArrayF<T extends any[]>(length: number, arr: T) {
const arrLength = Math.min(length, arr.length);
const arr2 = arr.slice(0, arrLength);
return reduceArrayF((prev, cur) => {
return exec(p => exec(c => {
p.push(c);
return p;
}, cur), prev);
}, [] as T | Promise<T>, arr2);
}
/**
* @memberof array
* @function
*/
export const takeArray:
(<T extends any[]>(length: number) =>
<U extends T>(arr: U) => ArrayPromiseReturnType<U>) &
(<T extends any[]>(length: number, arr: T) => ArrayPromiseReturnType<T>) =
/*#__PURE__*/ curry(takeArrayF);