2

将任何(等长)行数组转换为列数组的最优雅方法是什么?

例如:

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

# To    

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

这是我到目前为止所拥有的:

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

甚至可能有一个 1-liner 可以做到吗?

4

4 回答 4

6

在 Javascript 中,如果您在使用 ECMAScript 5 数组方法的环境中工作,则该map()函数可以很好地解决这个问题:

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

如果你取消了换行符,这可能是一个单行。:)

咖啡脚本:

grid[0].map (col, i) -> grid.map (row) -> row[i]
于 2011-05-11T23:01:30.993 回答
4

不要将 for..in 与顺序很重要的数组一起使用!!

将 for..in 与数组一起使用具有以下危险:

  1. 将返回数组的所有可枚举属性,包括 Array.prototype 上的属性和数组本身,因此您必须绝对确信没有发生此类扩展,或者您必须执行 hasOwnProperty 和数字索引检查

  2. 返回键的顺序无法保证并且很容易受到干扰 - IE 按添加顺序返回它们,因此如果它们被乱序添加(例如,使用递减的 while 循环,这很常见)它们将返回以相反的顺序

在 Firefox 和 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

在顺序很重要的情况下,在您按所需顺序显式访问键的情况下使用循环。这也适用于对象,因为在 javascript 中,使用 for..in 为所有对象返回属性的顺序取决于实现并且因浏览器而异(请注意,在 javascript 中,一切都是对象)。

For..in 可以与上述问题不重要或已处理的数组一起使用。它是用于稀疏数组和访问非数字可枚举属性的便捷工具。

一个通用的转置函数是:

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

它可以缩短和优化,但以上是一个性能合理且易于维护的功能。

于 2011-05-11T23:38:36.647 回答
2

尝试这个:

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
}

会给你一个结果:

new_grid = [
   [1,4],
   [2,5],
   [3,6],
]
于 2011-05-11T22:39:37.230 回答
2

咖啡脚本:

((row[i] for row in grid) for i in [0...grid[0].length])
于 2011-05-11T22:54:59.513 回答