Convertir un tableau de lignes en un tableau de colonnes

Quelle serait la façon la plus élégante de transformer n'importe quelle série de lignes (de longueur égale) en une série de colonnes?

Par exemple:

[1,2,3] [4,5,6] # To [1,4] [2,5] [3,6] 

C'est ce que j'ai jusqu'ici:

 grid = [ [1,2,3] [4,5,6] ] grid2 = [] for i in grid[0] grid2.push [] for row, y in grid for el, x in row grid2[x].push el 

Est-ce qu'il y a peut-être même un 1-liner qui le ferait?

Dans Javascript, si vous travaillez dans un environnement avec des méthodes de tableau ECMAScript 5, la fonction map() fonctionne bien pour cela:

 var grid2 = grid[0].map(function(col, i) { return grid.map(function(row) { return row[i]; }); }); 

Cela pourrait être un one-liner si vous avez tué les sauts de ligne. 🙂

CoffeeScript:

 grid[0].map (col, i) -> grid.map (row) -> row[i] 

N'utilisez pas pour … avec des tableaux où l'ordre est important !!

L'utilisation de … avec des tableaux présente les dangers suivants:

  1. Toutes les propriétés énumérables du tableau seront renvoyées, y compris celles sur Array.prototype et le réseau lui-même, de sorte que vous devez être absolument sûr qu'aucune extension n'a eu lieu ou que vous devez effectuer des contrôles d'ouverture de propriété et de numérotation numérique

  2. L'ordre dans lequel les clés sont retournées n'est pas garanti et peut être facilement perturbé – IE les renvoie dans l'ordre où elles sont ajoutées, donc si elles sont ajoutées hors service (par exemple en utilisant une boucle de décrémentation, ce qui est assez courant), ils seront retournés Dans l'ordre inverse

Essayez les éléments suivants dans Firefox et IE:

 var a = [0,1,2,3]; var b = []; var i = a.length; while (i--) { b[i] = a[i]; } var s = []; for (var p in b) { s.push(b[p]); } alert(b + '\n' + s); // Firefox: 0,1,2,3 // 0,1,2,3 // IE: 0,1,2,3 // 3,2,1,0 

Lorsque l'ordre est important, utilisez uniquement des boucles où vous accédez explicitement aux clés dans l'ordre dont vous avez besoin. Cela s'applique également aux objets, car en javascript, l'ordre dans lequel les propriétés sont renvoyées en utilisant for..in pour tous les objets dépend de l'implémentation et varie selon les navigateurs (en notant que javascript, tout est un objet).

For..in est correct d'utiliser avec des tableaux où les problèmes ci-dessus ne sont ni importants ni traités. C'est un outil pratique pour les tableaux épars et l'accès aux propriétés non numériques énumérables.

Une fonction de transposition générique est:

 function rows2cols(a) { var r = []; var t; for (var i=0, iLen=a.length; i<iLen; i++) { t = a[i]; for (var j=0, jLen=t.length; j<jLen; j++) { if (!r[j]) { r[j] = []; } r[j][i] = t[j]; } } return r; } 

Il peut être raccourci et optimisé, mais ce qui précède est une fonction raisonnablement performante et facilement maintenue.

CoffeeScript:

 ((row[i] for row in grid) for i in [0...grid[0].length]) 

Essaye ça:

 var new_grid = []; for(var i = 0; i < grid[0].length; i++){ new_grid.push([grid[0][i], grid[1][i]]); // this is all under assumption that all the arrays are the same size } 

Vous obtiendrez un résultat de:

 new_grid = [ [1,4], [2,5], [3,6], ]