-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathindex.ts
52 lines (45 loc) · 1.23 KB
/
index.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
43
44
45
46
47
48
49
50
51
52
export function lazy<T>(array: T[]): (fn: Fn<T>) => T[]
export function lazy<T>(fn: Fn<T>): T[]
/**
* Returns an array that look just like a regular JavaScript array, but is computed lazily.
*
* @param array (Optional) Initial value
* @param fn Function that takes a numerical index, and returns a value
*/
export function lazy<T>(arg: T[] | Fn<T>) {
if (Array.isArray(arg)) {
return lazyInternal(arg)
}
return lazyInternal<T>([])(arg)
}
export type Fn<T> = (index: number) => T
function lazyInternal<T>(array: T[]) {
return (fn: Fn<T>) => {
const processed: { [index: string]: true } = {}
for (let n = 0; n < array.length; n++) {
processed[n] = true
}
return new Proxy(array, {
deleteProperty(_, n: number) {
return delete processed[n]
},
get(array, key) {
const _key = +(key as any)
if (typeof key === 'string' && !Number.isNaN(_key)) {
if (!(key in processed)) {
array[_key] = fn(_key)
processed[key] = true
}
return array[_key]
}
return array[key as any]
},
has(array, index: number) {
return array.length > index
},
set() {
return false
}
})
}
}