257 votes

Transposition d'un tableau 2D en JavaScript

J'ai un tableau de tableaux, quelque chose comme.. :

[
    [1,2,3],
    [1,2,3],
    [1,2,3],
]

Je voudrais le transposer pour obtenir le tableau suivant :

[
    [1,1,1],
    [2,2,2],
    [3,3,3],
]

Il n'est pas difficile de le faire par programmation en utilisant des boucles :

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;
}

Cependant, cela semble encombrant, et j'ai l'impression qu'il devrait y avoir un moyen plus facile de le faire. Y en a-t-il un ?

14voto

Andrew Tatomyr Points 373

Net et pur :

[[0, 1], [2, 3], [4, 5]].reduce((prev, next) => next.map((item, i) =>
    (prev[i] || []).concat(next[i])
), []); // [[0, 2, 4], [1, 3, 5]]

Les solutions précédentes peuvent conduire à un échec dans le cas où un tableau vide est fourni.

Le voici sous forme de fonction :

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]]));

Mise à jour. On peut l'écrire encore mieux avec l'opérateur d'étalement :

const transpose = matrix => matrix.reduce(
    ($, row) => row.map((_, i) => [...($[i] || []), row[i]]), 
    []
)

10voto

Vous pouvez le faire sur place en ne faisant qu'une seule passe :

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;
    }
  }
}

9voto

Juste une autre variation utilisant Array.map . L'utilisation des indices permet de transposer les matrices où M != N :

// Get just the first row to iterate columns first
var t = matrix[0].map(function (col, c) {
    // For each column, iterate all rows
    return matrix.map(function (row, r) { 
        return matrix[r][c]; 
    }); 
});

Pour transposer, il suffit de mettre en correspondance les éléments par colonne, puis par ligne.

8voto

Nina Scholz Points 17120

Une autre approche consiste à itérer le tableau de l'extérieur vers l'intérieur et à réduire la matrice en mettant en correspondance les valeurs internes.

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));

5voto

Khnle - Kevin Le Points 3415

Si vous avez la possibilité d'utiliser Ramda JS et la syntaxe ES6, voici une autre façon de procéder :

const transpose = a => R.map(c => R.map(r => r[c], a), R.keys(a[0]));

console.log(transpose([
  [1, 2, 3, 4],
  [5, 6, 7, 8],
  [9, 10, 11, 12]
])); // =>  [[1,5,9],[2,6,10],[3,7,11],[4,8,12]]

<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.22.1/ramda.min.js"></script>

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X