/
each.ts
42 lines (37 loc) · 954 Bytes
/
each.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
import { isArrayLike } from './is-array-like'
import { type AnyMap } from './types'
const iterateArray = <T>(
arr: T[],
fn: (a: T, b: string) => T,
): T[] => {
return arr.map((x: T, i: number) => fn(x, i.toString()))
}
type IOFn <T> = (a: T, b: string) => AnyMap
const iterateObject = <T>(
obj: AnyMap,
fn: IOFn<T>,
): AnyMap => {
const r: AnyMap = {}
for (const prop in obj) {
if (Object.hasOwn(obj, prop)) {
r[prop] = fn(obj[prop] as T, prop)
}
}
return r
}
/**
* Takes an array or object
* and a function, and runs the function
* on each element
* @example
* each([ 'a', 'b', 'c' ], id) // => 'a'
*/
export const each = <T>(
xs: (any[] | Record<string, any> | string),
fn: ((a: any | null | undefined, b: number | string) => T),
): Record<string, any> | T[] => {
if (isArrayLike(xs)) {
return iterateArray((xs as any[]), fn)
}
return iterateObject((xs as Record<string, any>), fn as IOFn<T>)
}