import { ObjectInterface } from "@daybrush/utils";
import { headArray, tailArray, reduceArrayF } from "../array/array";
import { exec } from "../utils";
import { CheckPromiseType, CheckObjectType, CheckPromiseObjectType, PromiseReturnType } from "../types";
/**
* @namespace object
*/
/**
* @memberof object
* @typedef
*/
export type EachObjectCallbackType<T, U, R extends ObjectInterface<T | Promise<T>> = ObjectInterface<T>> =
(value: T, key: string, obj: R) => U;
/**
* @memberof object
* @typedef
*/
export type ReduceObjectCallbackType<T, U, R extends ObjectInterface<U | Promise<U>> = ObjectInterface<U>> =
(previousValue: T, currentValue: U, currentIndex: string, obj: R) => T;
/**
* @memberof object
*/
export function reduceObjectF<T, U = T>(
callbackFn: ReduceObjectCallbackType<T, U>,
initial: T,
obj: ObjectInterface<U>): T {
let cur = initial;
for (const key in obj) {
cur = callbackFn(cur, obj[key], key, obj);
}
return cur;
}
/**
* @memberof object
*/
export function eachObjectF<T = any>(f: EachObjectCallbackType<T, void>, obj: ObjectInterface<T>):
ObjectInterface<T> {
for (const key in obj) {
f(obj[key], key, obj);
}
return obj;
}
/**
* @memberof object
*/
export function mapObjectF<T = any, U = any>(f: EachObjectCallbackType<T, U>, obj: ObjectInterface<T>):
ObjectInterface<U> {
const rv: ObjectInterface<U> = {};
for (const key in obj) {
rv[key] = f(obj[key], key, obj);
}
return rv;
}
/**
* @memberof object
*/
export function filterObjectF<T = any>(f: EachObjectCallbackType<T, boolean>, obj: ObjectInterface<T>):
ObjectInterface<T> {
const rv: Partial<ObjectInterface<T>> = {};
for (const key in obj) {
f(obj[key], key, obj) && (rv[key] = obj[key]);
}
return rv;
}
/**
* @memberof object
*/
export function values<T>(obj: ObjectInterface<T>): T[] {
return Object.values(obj);
}
/**
* @memberof object
*/
export function keys<T extends ObjectInterface<T>>(obj: ObjectInterface<T>): Array<keyof T & string> {
return Object.keys(obj);
}
/**
* @memberof object
*/
export function headObject<T>(obj: ObjectInterface<T>): T {
return headArray(values(obj));
}
/**
* @memberof object
*/
export function tailObject<T>(obj: ObjectInterface<T>): T {
return tailArray(values(obj));
}
export function takeObjectF<T extends ObjectInterface<any>>(length: number, obj: T):
CheckPromiseType<CheckObjectType<T>,
PromiseReturnType<ObjectInterface<CheckPromiseObjectType<T>>>,
ObjectInterface<CheckPromiseObjectType<T>>>;
/**
* @memberof object
*/
export function takeObjectF<T extends ObjectInterface<any>>(length: number, obj: T) {
const objkeys = keys(obj);
const arrLength = Math.min(length, objkeys.length);
const objkeys2 = objkeys.slice(0, arrLength);
return reduceArrayF((prev, cur) => {
return exec(p => exec(c => {
p[cur] = obj[cur];
return p;
}, cur), prev);
}, {} as T | Promise<T>, objkeys2);
}