-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.ts
43 lines (37 loc) · 1.37 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
export interface ConditionFn<T = any> {
(chunk: T[], i: number, array: T[], chunksSize: number): boolean
}
type Condition<T = any> = ConditionFn<T> | number
function conditionIsNumber(condition: Condition): condition is number {
return typeof condition === 'number'
}
function buildSmallerThan<T>(size: number): ConditionFn<T> {
return chunk => chunk.length >= size
}
function getLast<T>(array: T[]): T | undefined {
return array[array.length - 1]
}
function push<T = any>(array: T[], item: T): T[] {
array.push(item)
return array
}
export function chunkBy<T = any>(array: T[], condition: number): T[][]
export function chunkBy<T = any>(array: T[], condition: ConditionFn<T>): T[][]
export function chunkBy<T = any>(array: T[], condition: Condition<T>): T[][] {
if (array === undefined) throw new Error('Missing array')
if (condition === undefined) throw new Error('Missing condition')
if (!array.length) return []
if (conditionIsNumber(condition)) {
const lengthCondition = buildSmallerThan<T>(condition)
return chunkBy<T>(array, lengthCondition)
}
const chunks = array.reduce<T[][]>((acc, item, idx) => {
const lastChunk = getLast<T[]>(acc)
if (!lastChunk) return push(acc, [item])
const isValid = condition(lastChunk, idx, array, acc.length)
if (isValid) return push(acc, [item])
lastChunk.push(item)
return acc
}, [])
return chunks
}