// 你的答案
type Chunk<T extends any[],U extends number,R extends any[] = [],S extends any[] = [],B extends any[] = [] > = S['length'] extends U ? Chunk<T,U,[...R,B],[],[]> :
T extends [infer RR,...infer LL]? Chunk<LL,U,R,[...S,1],[...B,RR]>: B extends [] ? R : [...R,B]
Solution by yuadh #36694
// your answers
// 取出前N个
type PopN<T extends any[], N, Count extends any[] = []> =
Count['length'] extends N ? [] : T extends [infer R, ...infer Rest] ? [R, ...PopN<Rest,N,[...Count,1]>] : []
// 去除前N个后的剩余部分
type RestN<T extends any[], N, Count extends any[] = []> =
Count['length'] extends N ? T : T extends [infer R, ...infer Rest] ? RestN<Rest, N, [...Count, 1]> : []
// 从T里取出0...N的数组
// chunk剩余部分
type Chunk<T extends any[], N extends number> =
T extends [] ? [] : [PopN<T, N>, ...Chunk<RestN<T, N>, N>]
Solution by duanlvxin #36570
type Chunk<
T extends any[], // T는 배열 (튜플)
N extends number, // N은 숫자 (청크 크기)
R extends any[] = [] // R은 임시적으로 담을 배열
> = T extends [infer First, ...infer Rest] // 첫 번째 요소를 분리
? R['length'] extends N // 임시 배열 R의 길이가 N이면, 한 덩어리 완성
? [R, ...Chunk<T, N>] // 현재 청크를 결과에 추가하고, 다시 Chunk 호출
: Chunk<Rest, N, [...R, First]> // 현재 요소를 R에 추가하고 계속 진행
: R extends [] // 남은 R이 비어 있으면
? [] // 더 이상 나눌 것이 없음
: [R]; // 마지막 남은 청크를 추가
Solution by adultlee #35842
type Chunk<A extends Array<unknown>, Split extends number, Temp extends Array<unknown> = [], R extends Array<unknown> = []> =
A extends [infer AF, ...infer AR]
? [...Temp, AF]['length'] extends Split
? Chunk<AR, Split, [], [...R, [...Temp, AF]]>
: Chunk<AR, Split, [...Temp, AF], R>
: Temp['length'] extends 0 ? R : [...R, Temp]
Solution by gangnamssal #35700
type Chunk< T extends any[], N , R extends any[] = [], I extends any[] = []> =
T extends [infer H, ... infer B] ? R['length'] extends N ? Chunk<B,N,[H],[...I, R]>: Chunk<B,N,[...R,H],I> : R extends [] ? [...I,...R] : [...I,R]
Solution by Mohmn #35370
type Chunk<
P extends any[],
N extends number,
A extends any[] = []
> = N extends keyof P
? N extends A['length']
? [A, ...Chunk<P, N>]
: P extends [infer S, ...infer R]
? Chunk<R, N, [...A, S]>
: [A] extends [[]]
? A
: [A]
: A
Solution by Keith-Web3 #35015
type Chunk<T extends any[], L extends number = 1, U extends any[] = []> = U['length'] extends L ? [U, ...Chunk<T, L>] :
T extends [infer R, ...infer rest] ?
Chunk<rest, L, [...U, R]> : U extends [] ? U : [U]
Solution by ouzexi #34073
type Chunk<T extends any[],N extends number> =
T extends [] ? [] : // 1
T extends [infer L,infer M,...infer R] // 2
? L extends any[] // 3
? L['length'] extends N // 4
? [L,...Chunk<[M,...R],N>] // 5
: Chunk<[[...L,M],...R],N> // 6
: Chunk<[[L],...[M,...R]],N> // 7
: T[0] extends any[] // 8
? T : [T] // 9
看了很多答案,似乎都是带了第二个参数的,其实没有必要。 逐行解释
T extends [] ? [] :
这句是为了判空
T extends [infer L,infer M,...infer R]
这句是关键,假设为了调整数组的大小,那么左边数组必须加入一个新参数,所以需要从右边借一个参数过来。那么问题来了 这个句子什么时候才会返回,看下面这个例子。
[1,2,3,4] extends [infer L,infer M,...infer R] ? L | M | R : [] // 1 | 2 | [3,4]
[1,2,3] extends [infer L,infer M,...infer R] ? L | M | R : [] // 1 | 2 | [3]
[1,2] extends [infer L,infer M,...infer R] ? L | M | R //2 | 1 | [] 说实在的这个联合类型顺序是怎么回事,我是一点都搞不懂,知道的大佬能说一下吗
[1] extends [infer L,infer M,...infer R] ? L | M | R : [] // []
也就是说,只有当T
参数大于一个的时候才会进入正确的通道。并获得参数L``M``R
,然后来看这一句
L extends any[]
判断第一个参数是不是数组,如果不是说明是第一次进去,那么你就需要往L
外面套上一层变成[L]
,所以需要第7行Chunk<[[L],...[M,...R]],N> // 7
。
当L
是一个数组之后我们需要第4行 L['length'] extends N // 4
来判断这个数组的长度是否等于N
,不是的话就往左边加入新参数M
继续遍历,也就是第6行: Chunk<[[...L,M],...R],N> // 6
,如果说长度等于N
的话,就可以进入下面的第5行了 [L,...Chunk<[M,...R],N>] // 5
,继续往右遍历,直到T
只剩下[最后一个参数]
,这时候数组不满足于第2行T extends [infer L,infer M,...infer R] // 2
进入了第8行T[0] extends any[] // 8
,判断第一个参数是不是数组,是的话就直接返回T
,不是的话就往外面套一层变成[T]
不过笔者发现一个小bug就是了,你往里面放一个带数组的数组就会出现问题,如下
Chunk<[1, 2, [3, 4]], 2> // [[1, 2], [3, 4]]
Chunk<[1, 2, [3, 4]], 1> // [[1], [2], [3, 4]]
希望作者能完善一下样例和说明,毕竟上面这个不管怎么解释都有点说不太过去,我自己也不了解chunk的原理,所以也不知道这样划分对不对
Solution by xdrlmm #33957
// your answers
type Chunk<T extends any[], N extends number, Res extends any[] = [], C extends any[] = []> =
C['length'] extends N ? Chunk<T, N, [...Res, C]> :
T extends [infer A, ...infer R] ? Chunk<R, N, Res, [...C, A]> : C extends [] ? Res : [...Res, C]
Solution by heyuelan #33856
type Chunk<T extends any[], S extends number, Res extends any[] = [], Part extends any[] = [] > =
T extends [infer F, ...infer Rest]
? S extends Part['length']
? Chunk<Rest, S, [...Res, Part], [F]>
: Chunk<Rest, S, Res, [...Part, F]>
: Res extends []
? Part extends []
? []
: [Part]
: [...Res, Part]
Solution by PiligrimStas #33752
type _Chunk<T extends any[], U extends number, R extends any[] = []> = T extends [infer F, ...infer rest]
? R['length'] extends U
? [R, ..._Chunk<rest, U, [F]>]
: _Chunk<rest, U, [...R, F]>
: [R]
type Chunk<T extends any[], U extends number> = T extends [] ? [] : _Chunk<T, U>
Solution by rimo030 #32886
// your answers
type Chunk<
T extends any[],
N extends number = 1,
R extends any[] = [],
C extends any[] = []
> = T extends [infer F, ...infer Rest]
? C['length'] extends N
? Chunk<Rest, N, [...R, C], [F]>
: Chunk<Rest, N, R, [...C, F]>
: [...R, ...(C['length'] extends 0 ? [] : [C])];
Solution by TRIS-H #31637
type Chunk<
T extends any[],
N extends number,
Arr extends unknown[] = []
> = Arr["length"] extends N
? [Arr, ...Chunk<T, N>]
: T extends [infer First, ...infer res]
? Chunk<res, N, [...Arr, First]>
: Arr["length"] extends 0
? []
: [Arr];
Solution by sunsunmonkey #31542
type NumberToArray<T extends number, U extends boolean[] = []> =
U['length'] extends T ?
U :
NumberToArray<T, [...U, true]>
type TakeFirst<T extends unknown[], S extends number, U extends unknown[] = []> =
U['length'] extends S ?
U :
T extends [infer F, ...infer Rest] ?
TakeFirst<Rest, S, [...U, F]> :
T
type PopFirst<T extends unknown[], S extends number, U extends unknown[] = []> =
U['length'] extends S ?
T :
T extends [infer _, ...infer Rest] ?
PopFirst<Rest, S, [...U, true]> :
T
type WrapChunks<T extends unknown[], S extends number> =
PopFirst<T, S>['length'] extends 0 ?
[T] :
[TakeFirst<T, S>, ...Chunk<PopFirst<T, S>, S>]
type Chunk<T extends unknown[], S extends number> =
T['length'] extends 0 ?
[] :
WrapChunks<T, S>
/* _____________ Test Cases _____________ */
import type { Equal, Expect } from '@type-challenges/utils'
type cases = [
Expect<Equal<Chunk<[], 1>, []>>,
Expect<Equal<Chunk<[1, 2, 3], 1>, [[1], [2], [3]]>>,
Expect<Equal<Chunk<[1, 2, 3], 2>, [[1, 2], [3]]>>,
Expect<Equal<Chunk<[1, 2, 3, 4], 2>, [[1, 2], [3, 4]]>>,
Expect<Equal<Chunk<[1, 2, 3, 4], 5>, [[1, 2, 3, 4]]>>,
Expect<Equal<Chunk<[1, true, 2, false], 2>, [[1, true], [2, false]]>>,
]
Solution by gearonixx #30915
type Chunk<T extends unknown[], N extends number, C extends unknown[] = [], R extends unknown[] = []> = T extends [
infer F,
...infer Rest,
]
? C['length'] extends N
? Chunk<Rest, N, [F], [...R, C]>
: Chunk<Rest, N, [...C, F], [...R]>
: [...R, C];
Solution by leejaehyup #30829
type Chunk<T extends readonly any[], N extends number, C extends any[] = [], R extends any[] = []> =
C['length'] extends N
? Chunk<T, N, [], [...R, C]>
: T extends [infer TF, ...infer TR]
? Chunk<TR, N, [...C, TF], R>
: C extends []
? R
: [...R, C]
Solution by matallui #30809
type Chunk<T extends any[], N extends number, C extends any[] = [], Result extends any[] = []> =
C['length'] extends N
? Chunk<T, N, [], [...Result, C]>
: T extends [infer F, ...infer Rest]
? Chunk<Rest, N, [...C, F], Result>
: C extends []
? Result
: [...Result, C]
Solution by jazelly #30452
// your answers,// 增加一个C记录chunk的结果
type Chunk<
T extends unknown[],
U extends number,
C extends unknown[] = []
> = T extends [infer F, ...infer R]
? Equal<C['length'], U> extends true
? [C, ...Chunk<T, U, []>]
: Chunk<R, U, [...C, F]>
: C extends []
? []
: [C]
Solution by bebusy007 #30017
type Chunk<T extends any[], N extends number, A extends any[] = [], S extends any[] = []> =
T extends [infer F, ...infer Rest]
? A['length'] extends N
? Chunk<Rest, N, [F], [...S, A]>
: Chunk<Rest, N, [...A, F], S>
: A['length'] extends 0 ? S : [...S, A]
Solution by hesoso #29841
type Chunk<
Tuple extends unknown[],
N extends number,
Res extends unknown[] = [],
Pack extends unknown[] = []
> = Tuple extends [infer Head, ...infer Tail]
? Pack["length"] extends N
? Chunk<Tail, N, [...Res, Pack], [Head]>
: Chunk<Tail, N, Res, [...Pack, Head]>
: Pack extends []
? Res
: [...Res, Pack];
Solution by idebbarh #28842
type Pop<T extends any[], C extends number, S extends any[] = []> = S['length'] extends C
? S
: T extends []
? S
: T extends [infer First, ...infer Rest]
? Pop<Rest, C, [...S, First]>
: never
type Chunk<T extends any[], C extends number> = T extends []
? T
: T extends [...Pop<T, C>, ...infer Rest]
? [Pop<T, C>, ...Chunk<Rest, C>]
: never;
Solution by JohnhanLiu #28768
type Chunk<
T extends unknown[],
Size extends number,
Chunks extends unknown[] = [],
Count extends unknown[] = [],
Res extends unknown[] = []
> = Count["length"] extends Size
? Chunk<T, Size, [], [], [...Res, Chunks]>
: T extends [infer F, ...infer R]
? Chunk<R, Size, [...Chunks, F], [...Count, unknown], Res>
: Chunks["length"] extends 0
? Res
: [...Res, Chunks];
Solution by DoubleWoodLin #28743
type Chunk<
T extends readonly unknown[],
N extends number = 1,
Item extends unknown[] = [],
Result extends unknown[] = []> = T extends [] ? Item extends [] ? Result : [...Result, Item] : T extends [infer Pre, ...infer Next]
? [...Item, Pre]['length'] extends N
? Chunk<Next, N, [], [...Result, [...Item, Pre]]>
: Chunk<Next, N, [...Item, Pre], [...Result]>
: Result
Solution by jiechliu #27701
type Chunk<
T extends any[],
Y extends number,
N extends any[] = [],
M extends any[] = []
> = T extends [infer F, ...(infer R)]
? N["length"] extends Y
? Chunk<T, Y, [], [...M, N]>
: Chunk<R, Y, [...N, F], M>
: N extends []
? M
: [...M, N];
Solution by smileboyi #27075
type Chunk<T extends unknown[],num extends number,i extends unknown[] = [],arr extends unknown[][] = []> = T extends [] ? i extends [] ? arr : [...arr,i] :
T extends [infer A,...infer B] ?
i['length'] extends num ? Chunk<B,num,[A],[...arr,i]>:
Chunk<B,num,[...i,A],arr> : arr
Solution by WangZiChu199910252255 #26691
// your answers
type ChunkIter<A extends any[], L extends number, R extends any[] = []>
= A extends [infer F, ...infer T] ?
R['length'] extends L ? [R, ...ChunkIter<T, L, [F]>] : ChunkIter<T, L, [...R, F]>
: [R]
type Chunk<A extends any[], L extends number> = A extends [] ? [] : ChunkIter<A, L>
Solution by adoin #26248
type Chunk<T extends unknown[], N extends number, R extends unknown[] = []> = T extends [infer First, ...infer Rest]
? R['length'] extends N
? [R, ...Chunk<Rest, N, [First]>]
: [...Chunk<Rest, N, [...R, First]>]
: R['length'] extends 0 ? [] : [R]
Solution by retkiewi #25914
// your answers
type FixLengthTuple<N extends number, A extends any[] = []> =
A['length'] extends N
? A
: FixLengthTuple<N, [...A, any]>
type Chunk<T extends any[], U extends number> =
T extends [...FixLengthTuple<U> , ...infer Rest] // 这样子 Rest 就空出了前面 U 个 Element
? T extends [...infer R, ...Rest] // R 就是前 U 个 Element 组成的 Array
? [R, ...Chunk<Rest, U>]
: []
: T extends []
? []
: [T]
Solution by kiki-zjq #25299
type FixLengthTuple<N extends number, A extends any[] = []> =
A['length'] extends N
? A
: FixLengthTuple<N, [...A, any]>
type Chunk<T extends any[], U extends number> =
T extends [...FixLengthTuple<U> , ...infer Rest]
? T extends [...infer R, ...Rest]
? [R, ...Chunk<Rest, U>]
: []
: T extends []
? []
: [T]
Solution by Minato1123 #25120
type Chunk<T extends unknown[], U extends number, Result extends unknown[] = []> = T extends [infer First, ...infer Rest]
? Result['length'] extends U
? [Result, ...Chunk<T, U>]
: Chunk<Rest, U, [...Result, First]>
: Result extends []
? Result
: [Result]
Solution by NeylonR #25052