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 ?

331voto

Fawad Ghafoor Points 1617
output = array[0].map((_, colIndex) => array.map(row => row[colIndex]));

map appelle un callback une fois pour chaque élément d'un tableau, dans l'ordre, et construit un nouveau tableau à partir des résultats. callback n'est invoqué que pour les index du tableau qui ont des valeurs assignées ; il n'est pas invoqué pour les index qui ont été supprimés ou qui n'ont jamais été assignés.

callback est invoqué avec trois arguments : la valeur de l'élément, l'index de l'élément et l'objet Array à parcourir. [source]

97voto

yangshun Points 273

Beaucoup de bonnes réponses ici ! Je les ai regroupées en une seule réponse et j'ai mis à jour une partie du code pour une syntaxe plus moderne :

Des phrases inspirées par Fawad Ghafoor y Óscar Gómez Alcañiz

function transpose(matrix) {
  return matrix[0].map((col, i) => matrix.map(row => row[i]));
}

function transpose(matrix) {
  return matrix[0].map((col, c) => matrix.map((row, r) => matrix[r][c]));
}

Approche fonctionnelle style avec réduction par Andrew Tatomyr

function transpose(matrix) {
  return matrix.reduce((prev, next) => next.map((item, i) =>
    (prev[i] || []).concat(next[i])
  ), []);
}

Lodash/Underscore par marcel

function tranpose(matrix) {
  return _.zip(...matrix);
}

// Without spread operator.
function transpose(matrix) {
  return _.zip.apply(_, [[1,2,3], [1,2,3], [1,2,3]])
}

Une solution encore plus simple de Lodash/Underscore par Vigrant

_.unzip(matrix);

L'approche vanille

function transpose(matrix) {
  const rows = matrix.length, cols = matrix[0].length;
  const grid = [];
  for (let j = 0; j < cols; j++) {
    grid[j] = Array(rows);
  }
  for (let i = 0; i < rows; i++) {
    for (let j = 0; j < cols; j++) {
      grid[j][i] = matrix[i][j];
    }
  }
  return grid;
}

Approche Vanilla in-place ES6 inspirée par Emanuel Saringan

function transpose(matrix) {
  for (var i = 0; i < matrix.length; i++) {
    for (var j = 0; j < i; j++) {
      const temp = matrix[i][j];
      matrix[i][j] = matrix[j][i];
      matrix[j][i] = temp;
    }
  }
}

// Using destructing
function transpose(matrix) {
  for (var i = 0; i < matrix.length; i++) {
    for (var j = 0; j < i; j++) {
      [matrix[i][j], matrix[j][i]] = [matrix[j][i], matrix[i][j]];
    }
  }
}

59voto

Mahdi Jadaliha Points 1123

Voici mon implémentation dans un navigateur moderne (sans dépendance) :

transpose = m => m[0].map((x,i) => m.map(x => x[i]))

42voto

Joe Points 18328

Vous pourriez utiliser underscore.js

_.zip.apply(_, [[1,2,3], [1,2,3], [1,2,3]])

35voto

marcel Points 2354

Le chemin le plus court avec lodash / underscore y es6 :

_.zip(...matrix)

donde matrix pourrait être :

const matrix = [[1,2,3], [1,2,3], [1,2,3]];

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