Matrix transposition in one line of code
A JavaScript function for transposing matrices.
A transposed matrix has properties that are very useful mathematically. As programmers, we sometimes work with two-dimensional arrays and need to extract information from a particular column. Matrix transposition is useful here too.
Until now, when my language did not support matrix manipulation natively or have a library for it, I used two loops to obtain the columns:
columns = new Array(matrix[0].length);
// Necesitamos inicializar cada elemento del arreglo columns como un array
// para poder utilizar push en el ciclo que extrae las columnas.
for (let j = 0; j < columns.length; j++) {
columns[j] = [matrix[0][j]];
}
// Iteramos todas las filas de la matrix
for (let i = 0; i < matrix.length; i++) {
// Iteramos todas las columnas
for (let j = 0; j < columns.length; j++) {
columns[j].push(this.matrix[i][j]);
}
}
The previous solution works, but my mentor recommended looking for something more idiomatic in JavaScript. After trying several approaches, I searched online for help because I could not find an efficient solution. What I found really surprised me; understanding it has broadened how I approach this kind of problem. Here is the solution:
columns = matrix[0].map((_, colIndex) => matrix.map(row => row[colIndex]));
Short, precise, elegant and cryptic the first time you see it. The idea is to nest two map functions.
The first map extracts the column indexes from matrix[0]. We are not interested in the element's value, so we use _.
matrix[0].map((_, colIndex))
The second extracts the elements of the column.
matrix.map(row => row[colIndex])
I found the solution here: Stack Overflow, Web Archive.
Implementing the same idea with two loops would look like this:
// Iteramos la primera fila de la matrix
for (let i = 0; i < matrix[0].length; i++) {
// Iteramos todas las filas de la matrix
for (let j = 0; j < matrix.length; j++) {
// Extraemos el valor del elemento en la columna i
columns[i].push(this.matrix[j][i]);
}
}
One thing I did not understand was why we could use a variable declared outside a function. The JavaScript manual explains it very well: let: Scoping rules.