Open utterances-bot opened 2 years ago
Here's my naïve initial attempt (before reading this solution):
type DecrementMap = {
5: 4;
4: 3;
3: 2;
2: 1;
1: 0;
};
type Decrement<N extends number> = N extends keyof DecrementMap
? DecrementMap[N]
: never;
type Chunk<
Arr extends readonly unknown[],
N extends number,
C extends number = N,
Acc extends readonly unknown[] = [],
CurrentAcc extends readonly unknown[] = []
> = Arr extends [infer H, ...infer T]
? C extends 0
? // counter is done
Chunk<Arr, N, N, [...Acc, CurrentAcc], []> // reset counter and push current into acc
: // counter was decreased
Chunk<T, N, Decrement<C>, Acc, [...CurrentAcc, H]> // decrement counter and push head into current
: CurrentAcc extends []
? Acc
: [...Acc, CurrentAcc]; // if not empty, add current
Wow, what an elegant result!
Share my solution which is accidentally tail-recursive for comparison and disscusion.
type Flatten<T extends any[][]> = T extends [infer First extends any[], ... infer Rest extends any[][]] ? [...First, ...Flatten<Rest>] : []
type Chunk<T extends any[], N extends number, R extends any[][] = [[]]> =
T extends []
? []
: T['length'] extends Flatten<R>['length']
? R
: R extends [...infer Rest extends any[][], infer Last extends any[]]
? Last['length'] extends N
? Chunk<T, N, [...Rest, Last, []]>
: Chunk<T, N, [...Rest, [...Last, T[Flatten<R>['length']]]]>
: never
Slightly readable...
type Chunk<T, N, A extends unknown[] = [], L = A["length"]> = T extends [infer F, ...infer Other]
? (L extends N ? [A, ...Chunk<T, N>] : Chunk<Other, N, [...A, F]>)
: (L extends 0 ? [] : [A]);
My first take on a tail recursive approach
type Chunk<
T extends unknown[],
N extends number,
Acc extends unknown[][] = [[]]
> = [T, Acc] extends [
[infer Head, ...infer Tail],
[...infer FirstPart extends unknown[][], infer Last extends unknown[]]
]
? Chunk<
Tail,
N,
Last["length"] extends N
? [...FirstPart, Last, [Head]]
: [...FirstPart, [...Last, Head]]
>
: Acc extends [[]]
? []
: Acc;
Chunk
This project is aimed at helping you better understand how the type system works, writing your own utilities, or just having fun with the challenges.
https://ghaiklor.github.io/type-challenges-solutions/en/medium-chunk.html