forked from sheepzh/time-tracker-4-browser
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy patharray.ts
More file actions
83 lines (77 loc) · 2.08 KB
/
array.ts
File metadata and controls
83 lines (77 loc) · 2.08 KB
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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
/**
* Copyright (c) 2022 Hengyang Zhang
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
/**
* Group by
*
* @param arr original array
* @param keyFunc key generator
* @returns grouped map
* @since 1.0.0
*/
export function groupBy<T, R>(
arr: T[],
keyFunc: (e: T) => string | number,
downstream: (grouped: T[], key: string) => R
): { [key: string]: R } {
const groupedMap: { [key: string]: T[] } = {}
arr.forEach(e => {
const key = keyFunc(e)
if (key === undefined || key === null) {
return
}
const existArr: T[] = groupedMap[key] || []
existArr.push(e)
groupedMap[key] = existArr
})
const result = {}
Object.entries(groupedMap)
.forEach(([key, grouped]) => result[key] = downstream(grouped, key))
return result
}
/**
* Rotate the array without new one returned
*
* @param arr the targe array
* @param count count to rotate, must be positive, or 1 is default
* @param rightOrLeft rotate right or left, true means left, false means right, default is false
*/
export function rotate<T>(arr: T[], count?: number, rightOrLeft?: boolean): void {
let realTime = 1
if (count && count > 1) {
realTime = count
}
const operation = !!rightOrLeft
// Right
? (a: T[]) => a.unshift(a.pop())
// Left
: (a: T[]) => a.push(a.shift())
for (; realTime > 0; realTime--) {
operation(arr)
}
}
/**
* Summarize
*
* @param arr target arr
*/
export function sum(arr: number[]): number {
return arr?.reduce?.((a, b) => (a || 0) + (b || 0), 0) ?? 0
}
/**
* @since 2.1.0
* @returns null if arr is empty or null
*/
export function average(arr: number[]): number {
if (!arr?.length) return null
return sum(arr) / arr.length
}
export function allMatch<T>(arr: T[], predicate: (t: T) => boolean): boolean {
return !arr?.filter?.(e => !predicate?.(e))?.length
}
export function anyMatch<T>(arr: T[], predicate: (t: T) => boolean): boolean {
return !!arr?.filter?.(e => predicate?.(e))?.length
}