将行数组转换为列数组

Aco*_*orn 1 javascript coffeescript

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

例如:

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

# To    

[1,4]
[2,5]
[3,6]
Run Code Online (Sandbox Code Playgroud)

这是我到目前为止:

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
Run Code Online (Sandbox Code Playgroud)

有没有可能会做到1-liner?

nra*_*itz 6

在Javascript中,如果您在使用ECMAScript 5数组方法的环境中工作,该map()函数可以很好地用于此:

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

如果你杀掉了换行符,这可能是一个单行.:)

CoffeeScript的:

grid[0].map (col, i) -> grid.map (row) -> row[i]
Run Code Online (Sandbox Code Playgroud)

  • 要支持旧环境,您可以修改`Array`原型或使用[underscore.js](http://documentcloud.github.com/underscore/)的`_.map`代替. (3认同)

Rob*_*obG 5

不要将 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
Run Code Online (Sandbox Code Playgroud)

如果顺序很重要,则仅使用按所需顺序显式访问密钥的循环。这也适用于对象,因为在 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;
}
Run Code Online (Sandbox Code Playgroud)

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