Don't use for..in with arrays where order is important!!
Using for..in with arrays has the following dangers:
All enumerable properties of the array will be returned, including those on Array.prototype and the array itself so either you must be absolutely confident that no such extensions have occurred, or you must do hasOwnProperty and numeric index checks
The order in which keys are returned is not guaranteed and can easily be disturbed - IE returns them in the order they are added, so if they are added out of order (e.g. using a decrementing while loop, which is quite common) they will returned in reverse order
Try the following in Firefox and 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
Where order is important, only use loops where you explicitly access keys in the order you require. This also applies to objects, since in javascript the order in which properties are returned using for..in for all objects is implementation dependent and varies across browsers (noting that in javascript, everything is an object).
For..in is OK to use with arrays where the above issues are either not important or are dealt with. It is a handy tool for sparse arrays and accessing non-numeric enumerable properties.
A generic transpose function is:
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;
}
It can be shortened and optimisied, but the above is a reasonably performant and easily maintained function.