Tengo una serie de matrices, algo así como:
[
[1,2,3],
[1,2,3],
[1,2,3],
]
Me gustaría transponerlo para obtener la siguiente matriz:
[
[1,1,1],
[2,2,2],
[3,3,3],
]
No es difícil hacerlo mediante programación usando bucles:
function transposeArray(array, arrayLength){
var newArray = [];
for(var i = 0; i < array.length; i++){
newArray.push([]);
};
for(var i = 0; i < array.length; i++){
for(var j = 0; j < arrayLength; j++){
newArray[j].push(array[i][j]);
};
};
return newArray;
}
Esto, sin embargo, parece voluminoso, y siento que debería haber una manera más fácil de hacerlo. ¿Esta ahí?
javascript
arrays
matrix
transpose
ckersch
fuente
fuente
arrayLength
usa exactamente el parámetro? ¿Para asegurarse de no ir más allá de un cierto número de elementos en la matriz?Respuestas:
fuente
array[0].map
lugar dearray.map
?array[0].map
porque quiere iterar sin importar cuántas veces haya columnas,array.map
iterará cuántas filas hay.loops
son un 45% más lentos quemap
. Y sí, se transpone correctamente, por lo que la segunda ejecución devuelve la matriz inicial.Aquí está mi implementación en el navegador moderno (sin dependencia):
fuente
Podrías usar underscore.js
fuente
rambda
puede hacerloconst transpose = apply(zip)
camino más corto con
lodash
/underscore
yes6
:donde
matrix
podría estar:fuente
_.zip.apply(_, matrix)
Muchas buenas respuestas aquí! Los consolidé en una respuesta y actualicé parte del código para una sintaxis más moderna:
One-liners inspirados en Fawad Ghafoor y Óscar Gómez Alcañiz
Estilo de enfoque funcional con reducción por Andrew Tatomyr
Lodash / Underscore por marcel
Enfoque de vainilla
Enfoque de vainilla en el lugar ES6 inspirado en Emanuel Saringan
fuente
Aseado y puro:
Las soluciones anteriores pueden provocar fallas en caso de que se proporcione una matriz vacía.
Aquí está como una función:
Actualizar. Se puede escribir aún mejor con el operador de propagación:
fuente
Puede hacerlo en el lugar haciendo solo un pase:
fuente
[arr[j][j],arr[i][j]] = [arr[i][j],arr[j][j]]
pero no parece funcionar, ¿me estoy perdiendo algo?[arr[j][i], arr[i][j]] = [arr[i][j], arr[j][i]]
. Tenga en cuenta que tiene algunosarr[j][j]
términos que siempre se referirán a las celdas en diagonal.Solo otra variación usando
Array.map
. El uso de índices permite transponer matrices dondeM != N
:Todo lo que hay que hacer para transponer es mapear los elementos primero en columna, y luego por fila.
fuente
Si tiene la opción de usar la sintaxis de Ramda JS y ES6, esta es otra forma de hacerlo:
fuente
transpose
función ahora.Otro enfoque al iterar la matriz de afuera hacia adentro y reducir la matriz al mapear los valores internos.
fuente
Si usar RamdaJS es una opción, esto se puede lograr en una línea:
R.transpose(myArray)
fuente
Puede lograr esto sin bucles utilizando lo siguiente.
Array
Array.prototype.map
Array.prototype.reduce
Array.prototype.join
String.prototype.split
Se ve muy elegante y no requiere dependencias como jQuery de Underscore.js .
Minified
Aquí hay una demostración que hice. Observe la falta de bucles :-)
fuente
ES6 1liners como:
igual que el de Óscar, pero como prefieres rotarlo en sentido horario:
fuente
Editar: esta respuesta no transpondrá la matriz, sino que la rotará. No leí la pregunta cuidadosamente en primer lugar: D
rotación en sentido horario y antihorario:
fuente
Encontré las respuestas anteriores difíciles de leer o demasiado detalladas, así que escribo una. Y creo que esta es la forma más intuitiva de implementar la transposición en álgebra lineal, no se hace intercambio de valores , sino que simplemente se inserta cada elemento en el lugar correcto en la nueva matriz:
fuente
Creo que esto es un poco más legible. Utiliza
Array.from
y la lógica es idéntica al uso de bucles anidados:Si se trata de matrices de longitud desigual, debe reemplazar
arr[0].length
por otra cosa:fuente
fuente
fuente
Una implementación sin biblioteca en TypeScript que funciona para cualquier forma de matriz que no truncará sus matrices:
fuente
Una línea que no cambia la matriz dada.
fuente
fuente
No encontré una respuesta que me satisficiera, así que escribí una, creo que es fácil de entender e implementar y adecuada para todas las situaciones.
fuente
Como nadie hasta ahora mencionó un enfoque recursivo funcional aquí es mi opinión. Una adaptación de Haskell's
Data.List.transpose
.fuente