将任何(等长)行数组转换为列数组的最优雅方法是什么?
例如
[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?
答案 0 :(得分:6)
在Javascript中,如果您在使用ECMAScript 5数组方法的环境中工作,map()
函数可以很好地用于此:
var grid2 = grid[0].map(function(col, i) {
return grid.map(function(row) {
return row[i];
});
});
如果你杀了换行符,这可能是一个单行。 :)
<强> CoffeeScript的:强>
grid[0].map (col, i) -> grid.map (row) -> row[i]
答案 1 :(得分:3)
对数组使用for..in有以下危险:
将返回数组的所有可枚举属性,包括Array.prototype和数组本身的属性,因此您必须绝对确信没有发生此类扩展,或者您必须do hasOwnProperty和数字索引检查
无法保证返回键的顺序,并且很容易受到干扰 - 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;
}
它可以缩短和优化,但以上是一个相当高效且易于维护的功能。
答案 2 :(得分:2)
<强> CoffeeScript的:强>
((row[i] for row in grid) for i in [0...grid[0].length])
答案 3 :(得分:1)
试试这个:
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],
]