FE/type-challenge
4471. Zip
최토피
2023. 8. 7. 12:47
728x90
문제
In This Challenge, You should implement a type Zip<T, U>, T and U must be Tuple
type exp = Zip<[1, 2], [true, false]> // expected to be [[1, true], [2, false]]
cases
Zip<[1, 2], [true, false]> // expected to be [[1, true], [2, false]],
Zip<[1, 2, 3], ['1', '2']> // expected to be [[1, '1'], [2, '2']],
Zip<[], [1, 2, 3]> // expected to be, [] ,
Zip<[[1, 2]], [3]> // expected to be [[[1, 2], 3]],
문제 링크
풀이
조건
혹시라도 조건이 잘못 되었다면 댓글 달아주세요… 문제의 설명이 짧아서 주관적으로 해석한겁니다 ㅜ
- Zip<T, U>의 T,U 는 any[] 타입이어야 한다.
- T[N] 이 비어 있는 경우 더 이상 zip 하지 않는다.
- U[N] 이 비어 있는 경우 더 이상 zip 하지 않는다.
정답 - 2가지
첫번째
type Zip<T extends any[], U extends any[]> =
[T, U] extends [[infer T1, ...infer RestT], [infer U1, ...infer RestU]]
? [[T1, U1], ...Zip<RestT, RestU>]
: []
해설
조건 1을 위해 T, U에 타입 조건을 추가했습니다.
type Zip<T extends any[], U extends any[]> = any
그 후 T,U 에서 순차적으로 각 요소에 접근하기 위해 값이 있는지 확인하는 조건을 추가합니다.
type Zip<T extends any[], U extends any[]> = T extends [infer T1 ...infer RestT]
? U extends [infer U1, ...infer RestU]
? any
: any
: any
T와 U의 첫 번째 요소는 튜플로 만들고, 남은 RestT와 RestU는 다시 Zip을 진행합니다.
type Zip<T extends any[], U extends any[]> = T extends [infer T1 ...infer RestT]
? U extends [infer U1, ...infer RestU]
? [[T1, U2], ...Zip<RestT, RestU>]
: any
: any
조건 2와 3을 만족하기 위해서 해당 경우에는 []를 리턴하도록 합니다.
type Zip<T extends any[], U extends any[]> = T extends [infer T1 ...infer RestT]
? U extends [infer U1, ...infer RestU]
? [[T1, U2], ...Zip<RestT, RestU>]
: []
: []
리팩토링
두 개의 삼항연산을 하나로 합칩니다.
type Zip<T extends any[], U extends any[]> =
[T, U] extends [[infer T1, ...infer RestT], [infer U1, ...infer RestU]]
? [[T1, U1], ...Zip<RestT, RestU>]
: []
두번째
type Zip<T extends any[], U extends any[], V extends any[] = []> =
V['length'] extends T['length'] | U['length']
? V
: Zip<T, U, [...V, [T[V['length']], U[V['length']]]]>
해설
조건 1을 위해 T, U에 타입 조건을 추가했습니다.
type Zip<T extends any[], U extends any[]> = any
조건 2,3은 다음과 같은 하나의 조건으로 만들 수 있습니다. T와 U 중 더 작은 길이만큼만 Zip을 진행한다. 따라서 다음과 같이 이전 기록들을 담아둘 V 인자를 추가해서, 둘 중 작은 배열만큼만 진행하도록 할 수 있습니다.
type Zip<T extends any[], U extends any[], V extends any[] = []> =
V['length'] extends T['length'] | U['length']
? V
: []
V의 길이가 0에서부터 시작하므로, V의 길이에 해당하는 T,U의 요소를 가져와서 넣어줄 수 있습니다.
type Zip<T extends any[], U extends any[], V extends any[] = []> =
V['length'] extends T['length'] | U['length']
? V
: Zip<T, U, [...V, [T[V['length']], U[V['length']]]]>
혹시나 설명 중 오류가 있으면 언제든지 댓글, 피드백 부탁드리겠습니다!
728x90