type GenerateRow<M extends number[][], R extends any[] = [], C extends any[] = []> = R['length'] extends M['length'] ? [] : [M[R['length']][C['length']], ...GenerateRow<M, [...R, any], C>]
type Transpose<M extends number[][], R extends any[] = [], C extends any[] = []> = C['length'] extends M[0]['length'] ? [] : [GenerateRow<M, R, C>, ...Transpose<M, R, [...C, any]>]
Solution by 2083335157 #34976
type GetN<T extends number[][], N extends number = 0> = T extends [
infer S extends any[],
...infer R extends any[]
]
? [S[N], ...GetN<R, N>]
: T
type Transpose<T extends number[][], K extends any[] = []> = T extends []
? []
: [...K, any]['length'] extends T[0]['length']
? [GetN<T, K['length']>]
: K['length'] extends T[0]['length']
? T
: [GetN<T, K['length']>, ...Transpose<T, [...K, any]>]
type Matrix = Transpose<[[1]]> // expected to be [[1]]
type Matrix1 = Transpose<[[1, 2], [3, 4]]> // expected to be [[1, 3], [2, 4]]
type Matrix2 = Transpose<[[1, 2, 3], [4, 5, 6]]> // expected to be [[1, 4], [2, 5], [3, 6]]
type Matrix3 = Transpose<[]> // expected to be []
Solution by Keith-Web3 #34929
type TakeFirst<T extends number[]> = T extends [infer F, ...unknown[]] ? F : [];
type TakeRest<T extends number[]> = T extends [unknown, ...infer R] ? R : [];
type TakeEveryFirst<T extends number[][]> = T extends [
infer F extends number[],
...infer R extends number[][]
]
? [TakeFirst<F>, ...TakeEveryFirst<R>]
: [];
type TakeEveryRest<T extends number[][]> = T extends [
infer F extends number[],
...infer R extends number[][]
]
? [TakeRest<F>, ...TakeEveryRest<R>]
: [];
type Transpose<M extends number[][]> = M extends [][]
? []
: [TakeEveryFirst<M>, ...Transpose<TakeEveryRest<M>>];
Solution by yukicountry #34373
type Compose<M extends number[][], L extends number> = M extends [infer R extends number[], ...infer rest extends number[][]] ? [R[L], ...Compose<rest, L>] : []
type Transpose<M extends number[][], U extends 1[] = []> = M extends [infer R extends number[], ...any] ? R['length'] extends U['length'] ? [] :
[Compose<M, U['length']>, ...Transpose<M, [...U, 1]>] : []
Solution by ouzexi #34150
// your answers
type TransposeBase<T extends number[][], N extends number> =
T extends [infer A extends number[], ...infer R extends number[][]] ? [A[N], ...TransposeBase<R, N>] : []
type Transpose<M extends number[][], N extends number = M[0]['length'], Res extends any[] = []> =
Res['length'] extends N ? Res : Transpose<M, N, [...Res, TransposeBase<M, Res['length']>]>
Solution by heyuelan #33871
A very blunt solution ...
type InitRetItems<
M extends number[][],
Ret extends number[][] = []
> = Ret['length'] extends M[0]['length'] ? Ret : InitRetItems<M, [[], ...Ret]>;
type RemoveFirstItem<Arr extends any[]> = Arr extends [any, ...infer Rest]
? Rest
: [];
// append every line
type AppendEveryLine<
Line extends number[],
Ret extends number[][]
> = Line extends [infer FirstNum, ...infer Rest extends number[]]
? [[...Ret[0], FirstNum], ...AppendEveryLine<Rest, RemoveFirstItem<Ret>>]
: [];
type Transpose<
M extends number[][],
Ret extends number[][] = InitRetItems<M>
> = M extends [infer Arr extends number[], ...infer Rest extends number[][]]
? Transpose<Rest, AppendEveryLine<Arr, Ret>>
: Ret;
Solution by sunupupup #33481
type Transpose<M extends number[][]>
= M extends [infer M0 extends number[], ...any]
? {[I in keyof M0]: {[J in keyof M]: I extends keyof M[J] ? M[J][I] : never}}
: []
Solution by teamchong #33056
分析
[[1, 2, 3], [4, 5, 6]]
- 第一步, 取二维数组的第一个元素组成一个数组,取到的数组为: [1, 4]
,
- 第二步, 去除掉每个数组的第一个元素, 得到数组为: [[2, 4],[5, 6]]
- 第三步,递归重复第一步和第二步,将所有第一步执行的结果保存下来,即得到答案。代码如下:
// 取每个数组的第一个元素
type FirstEl<T extends any[][] = []> = T extends [
infer L,
...infer R extends any[][]
]
? L extends []
? FirstEl<R>
: L extends [infer L1, ...infer R1]
? [L1, ...FirstEl<R>]
: []
: [];
// 去掉第一个元素后得到的二维数组
type RemoveFirstEl<T extends any[][]> = T extends [
infer L,
...infer R extends any[][]
]
? L extends []
? RemoveFirstEl<R>
: L extends [infer L1, ...infer R1]
? R1 extends []
? RemoveFirstEl<R>
: [R1, ...RemoveFirstEl<R>]
: []
: [];
type Transpose<T extends number[][]> = T extends []
? []
: [FirstEl<T>, ...Transpose<RemoveFirstEl<T>>];
Solution by Vampirelee #32573
type AppendToRow<
M extends number[][],
Row extends number,
Val extends number,
C extends 0[] = []
> = M extends [infer L extends number[], ...infer R extends number[][]]
? Row extends C["length"]
? [[...L, Val], ...R]
: [L, ...AppendToRow<R, Row, Val, [...C, 0]>]
: [];
type Transpose<
M extends number[][],
Row_Idx extends 0[] = [],
Col_Idx extends 0[] = [],
MT extends number[][] = [],
Row = M[Row_Idx["length"]]
> = Row_Idx["length"] extends M["length"]
? MT
: Row extends [infer C extends number, ...infer RowRest]
? Transpose<
M,
Row_Idx,
[...Col_Idx, 0],
AppendToRow<
Row_Idx["length"] extends 0 ? [...MT, []] : MT,
Col_Idx["length"],
C
>,
RowRest
>
: Transpose<M, [...Row_Idx, 0], [], MT>;
Solution by vangie #32210
type Transpose<
M extends unknown[][],
_Acc extends unknown[][] = [],
> =
_Acc["length"] extends M[0]["length"]
? _Acc
: Transpose<M, [..._Acc, TransposeColumnToRow<M, _Acc["length"]>]>
;
type TransposeColumnToRow<
M extends unknown[][],
CurrentCol extends number,
Acc extends unknown[] = [],
> =
Acc["length"] extends M["length"]
? Acc
: TransposeColumnToRow<M, CurrentCol, [...Acc, M[Acc["length"]][CurrentCol]]>
;
Solution by sdrjs #31939
// your answers
type GetValuesByIndex<M extends number[][], I extends number> =
M extends [infer F extends number[], ...infer R extends number[][]]
? [F[I], ...GetValuesByIndex<R, I>]
: []
type Transpose<M extends number[][], U extends unknown[] = []> =
M extends []
? []
: U['length'] extends M[number]['length']
? []
: [GetValuesByIndex<M, U['length']>, ...Transpose<M, [...U, unknown]>]
Solution by milletlovemouse #30957
// your answers
type TransposeOne<T extends number[], R extends number[][], NR extends number[][] = []> =
T extends [infer F extends number, ...infer Rest extends number[]]
? R extends [infer RF extends number[], ...infer RRest extends number[][]]
? TransposeOne<Rest, RRest, [...NR, [...RF, F]]>
: TransposeOne<Rest, [], [...NR, [F]]>
: NR
type Transpose<M extends number[][], R extends number[][] = []> =
M extends [infer F extends number[], ...infer Rest extends number[][]]
? Transpose<Rest, TransposeOne<F, R>>
: R
Solution by enochjs #30543
type Transpose<
M extends number[][],
Row extends unknown[] = M extends [] ? [] : M[0]
> = {
[K in keyof Row]: {
[Key in keyof M]: K extends keyof M[Key] ? M[Key][K] : never;
};
};
Solution by DoubleWoodLin #28915
这题有点变态,意思是,将多个数组按照 index 进行重拍,这里的思路是每次把所有数组的同一位拿出来,构造成一个数组,这样每次可以处理完一位
例如 [[1, 2], [3, 4]]
,我们先把第一位拿出来 得到数组 [1, 3]
再拿第二位 [2, 4]
,合并就好
按照这个思路,我们需要一个方法用来获取二元数组中的某一位组成的数组,通过遍历 二维数组 M,递归可以得到结果 [F[I], ...Temp<Res, I>]
那么主流程只需要处理 获取的是哪一位即可,可以借助数组 length 来计算当前是获取第几位的值
type Temp<M extends number[][], I extends number> = M extends [infer F extends number[], ...infer Res extends number[][]]
? [F[I], ...Temp<Res, I>]
: []
type Transpose<M extends number[][], Res extends number[][] = []> = M extends [infer F extends number[], ...any]
? F['length'] extends Res['length']
? []
: [Temp<M, Res['length']>, ...Transpose<M, [...Res, any]>]
: []
Solution by linjunc #28364
/** Appends each Row[i] to each M_T[i].
*
* AppendDown<[], [1,2,3]> => [[1],[2],[3]]
* AppendDown<[[1],[2],[3]], [4,5,6]> => [[1,4],[2,5],[3,6]]
*/
type AppendDown<
M_T extends number[][],
Row extends number[],
Result extends number[][] = []
> = Row extends [
infer FirstVal extends number,
...infer RestVals extends number[]
]
? M_T extends [
infer FirstRow extends number[],
...infer RestRows extends number[][]
]
? AppendDown<RestRows, RestVals, [...Result, [...FirstRow, FirstVal]]>
: AppendDown<[], RestVals, [...Result, [FirstVal]]>
: Result;
type Transpose<M extends number[][], M_T extends number[][] = []> = M extends [
infer First extends number[],
...infer Rest extends number[][]
]
? Transpose<Rest, AppendDown<M_T, First>>
: M_T;
Solution by alythobani #27666
#25297 's solution is better for the origin test cases:
Expect<Equal<Transpose<[]>, []>>,
Expect<Equal<Transpose<[[1]]>, [[1]]>>,
Expect<Equal<Transpose<[[1, 2]]>, [[1], [2]]>>,
Expect<Equal<Transpose<[[1, 2], [3, 4]]>, [[1, 3], [2, 4]]>>,
Expect<Equal<Transpose<[[1, 2, 3], [4, 5, 6]]>, [[1, 4], [2, 5], [3, 6]]>>,
Expect<Equal<Transpose<[[1, 4], [2, 5], [3, 6]]>, [[1, 2, 3], [4, 5, 6]]>>,
Expect<Equal<Transpose<[[1, 2, 3], [4, 5, 6], [7, 8, 9]]>, [[1, 4, 7], [2, 5, 8], [3, 6, 9]]>>,
But, it can not pass these edge cases:
Expect<Equal<Transpose<[[], [4, 5, 6], [7, 8, 9]]>, [[4, 7], [5, 8], [6, 9]]>>,
Expect<Equal<Transpose<[[1, 2], [4, 5, 6], [7, 8, 9]]>, [[1, 4, 7], [2, 5, 8], [6, 9]]>>,
Expect<Equal<Transpose<[[1, 2, 3], [4, 5], [7, 8, 9]]>, [[1, 4, 7], [2, 5, 8], [3, 9]]>>,
Expect<Equal<Transpose<[[1, 2, 3], [4, 5, 6], [7, 8]]>, [[1, 4, 7], [2, 5, 8], [3, 6]]>>,
Expect<Equal<Transpose<[[1, 2], [4, 5], [7, 8, 9]]>, [[1, 4, 7], [2, 5, 8], [9]]>>,
Expect<Equal<Transpose<[[1, 2], [4, 5, 6], [7, 8]]>, [[1, 4, 7], [2, 5, 8], [6]]>>,
Expect<Equal<Transpose<[[1, 2, 3], [4, 5], [7, 8]]>, [[1, 4, 7], [2, 5, 8], [3]]>>,
I think we should consider to be compatible with these:
type MergeToResult<R extends number[][], M extends number[], newR extends number[][] = []> =
M extends [infer M1 extends number, ...infer RestM extends number[]]
? R extends [infer R1 extends number[], ...infer RestR extends number[][]]
? MergeToResult<RestR, RestM, [...newR, [...R1, M1]]>
: MergeToResult<R, RestM, [...newR, [M1]]>
: [...newR, ...R]
type Transpose<M extends number[][], R extends number[][] = []> =
M extends [infer M1 extends number[], ...infer Rest extends number[][]]
? Transpose<Rest, MergeToResult<R, M1>>
: R
Solution by drylint #27431
type Transpose<M extends number[][], T extends number[] = M[0]> = M extends [] ? [] : {
[K1 in keyof T]: {
[K2 in keyof M]: K1 extends keyof M[K2] ? M[K2][K1] : never
}
}
Solution by smileboyi #27303
type Transpose<M extends number[][],arr extends number[][] = [],item extends number[] = []> = arr['length'] extends M[0]['length'] ? arr :
item['length'] extends M['length'] ? Transpose<M,[...arr,item],[]> : Transpose<M,arr,[...item,M[item['length']][arr['length']]]>
Solution by WangZiChu199910252255 #27100
type TransposeBase<M extends any[][], I extends number> = M extends [infer First extends any[] , ...infer Rest extends any[][]] ?
[First[I], ...TransposeBase<Rest, I>] : [];
type Transpose<M extends number[][], C extends any[] = []> = M extends [infer First extends number[], ...any] ?
First["length"] extends C["length"] ? [] : [TransposeBase<M, C["length"]>, ...Transpose<M, [...C, any]>]
:
[];
Solution by shhhplus #26833
type GetValues<M extends number[][], I extends number = 0, R extends number[] = []> = M extends [infer F extends number[], ...infer Rest extends number[][]]
? GetValues<Rest, I, [...R, F[I]]>
: R
type Transpose2<M extends number[][], R extends number[][] = []> = M extends []
? []
: M[0]['length'] extends R['length']
? R
: Transpose2<M, [...R, GetValues<M, R['length']>]>
更好的写法: 25297
Solution by XkSuperCool #26095
type Col<T extends number[][], I extends number> = T extends [infer F extends number[], ...infer R extends number[][]] ? [F[I], ...Col<R, I>] : [];
type Transpose<M extends number[][], _Result extends number[][] = []> = _Result[`length`] extends M[0][`length`] ?
_Result/*return*/ : Transpose<M, [..._Result, Col<M, _Result[`length`]>]>;
Solution by E-uler #25376
type Transpose<M extends number[][],R = M['length'] extends 0?[]:M[0]> = {
[X in keyof R]:{
[Y in keyof M]:X extends keyof M[Y]?M[Y][X]:never
}
}
Solution by jiangshanmeta #25297