I\'ve got an array of arrays, something like:
[
[1,2,3],
[1,2,3],
[1,2,3],
]
I would like to transpose it to get the following
Neat and pure:
[[0, 1], [2, 3], [4, 5]].reduce((prev, next) => next.map((item, i) =>
(prev[i] || []).concat(next[i])
), []); // [[0, 2, 4], [1, 3, 5]]
Previous solutions may lead to failure in case an empty array is provided.
Here it is as a function:
function transpose(array) {
return array.reduce((prev, next) => next.map((item, i) =>
(prev[i] || []).concat(next[i])
), []);
}
console.log(transpose([[0, 1], [2, 3], [4, 5]]));
Update. It can be written even better with spread operator:
const transpose = matrix => matrix.reduce(
($, row) => row.map((_, i) => [...($[i] || []), row[i]]),
[]
)
You can do it in in-place by doing only one pass:
function transpose(arr,arrLen) {
for (var i = 0; i < arrLen; i++) {
for (var j = 0; j <i; j++) {
//swap element[i,j] and element[j,i]
var temp = arr[i][j];
arr[i][j] = arr[j][i];
arr[j][i] = temp;
}
}
}
A library-free implementation in TypeScript that works for any matrix shape that won't truncate your arrays:
const rotate2dArray = <T>(array2d: T[][]) => {
const rotated2d: T[][] = []
return array2d.reduce((acc, array1d, index2d) => {
array1d.forEach((value, index1d) => {
if (!acc[index1d]) acc[index1d] = []
acc[index1d][index2d] = value
})
return acc
}, rotated2d)
}
shortest way with lodash
/underscore
and es6
:
_.zip(...matrix)
where matrix
could be:
const matrix = [[1,2,3], [1,2,3], [1,2,3]];
I found the above answers either hard to read or too verbose, so I write one myself. And I think this is most intuitive way to implement transpose in linear algebra, you don't do value exchange, but just insert each element into the right place in the new matrix:
function transpose(matrix) {
const rows = matrix.length
const cols = matrix[0].length
let grid = []
for (let col = 0; col < cols; col++) {
grid[col] = []
}
for (let row = 0; row < rows; row++) {
for (let col = 0; col < cols; col++) {
grid[col][row] = matrix[row][col]
}
}
return grid
}
Another approach by iterating the array from outside to inside and reduce the matrix by mapping inner values.
const
transpose = array => array.reduce((r, a) => a.map((v, i) => [...(r[i] || []), v]), []),
matrix = [[1, 2, 3], [1, 2, 3], [1, 2, 3]];
console.log(transpose(matrix));