我写了这个方法来转置一个javascript数组
Array.prototype.transpose = function () {
let rows = this.length;
let cols = this[0].length;
let ret = [[]];
for (y=0;y<cols;y++)
for (x=0;x<rows;x++)
ret[y][x]=this[x][y]
return ret;
}
然而,这是非常低效的,因为它实际上复制了整个数据。
我更喜欢使用标记为transposed?
的标记arr[x][y]
如果已启用arr[y][x]
。
然后,函数transpose
只会切换它。
如何在javascript中完成?
答案 0 :(得分:4)
替代方案可能是使用proxies。它们允许您捕获对象成员访问权限(例如数组括号引用)并返回自定义值。
这是一个简单的实现,只支持get
访问索引和length
属性,但没有别的。如果你真的想,你可以扩展它以支持迭代,枚举,设置,数组方法(如join
,map
,...),...等,但如果你愿意的话到目前为止,并且真的会使用这些方法,那么问题确实变得是否值得所有的努力,因为如果你像你那样做总体性能可能会更好:将数组复制到其转置的计数器部分。 / p>
无论如何,这是:
var a = [ [1,2,3],
[4,5,6] ];
a.transposed = new Proxy(a, {
get: (arr, col) =>
+col >= 0 ? new Proxy({ length: a.length }, {
get: (obj, row) => +row >=0 ? arr[row][col] : obj[row]
})
: col == 'length' ? arr[0] && arr[0].length
: col == 'original' ? arr
: undefined
});
var t = a.transposed;
// Mutate a, to demo that also t shows the mutation:
a[0][2] = 3.5;
console.log('a = ', JSON.stringify(a));
console.log('a[0][2] = ', a[0][2], ', t[2][0] = ', t[2][0]);
console.log('a[0].length = ', a[0].length, ', t.length = ', t.length);
console.log('a.length = ', a.length, ', t[0].length = ', t[0].length);
// you can revert back to original array from the transposed one:
console.log('a === t.original?', a === t.original);
答案 1 :(得分:1)
我不认为你可以覆盖数组的[]
,我也相信如果可能的话会引入许多讨厌的错误。
快速解决方案可能是编写一个交换参数的实用程序函数:
var arr = [
['A', 'B', 'C'],
[1, 2, 3],
['x', 'y', 'z']
];
// Using a short, pure function:
var getVal = (arr, i, j) => arr[i][j];
var getTransposed = (arr, i, j) => getVal(arr, j, i);
console.log(getVal(arr, 1,2));
console.log(getTransposed(arr, 1,2));
// Using a "class"
var Transposer = function(arr) {
var myArr = arr.slice();
var transposed = false;
return {
toggle: () => transposed = !transposed,
isTransposed: () => transposed,
getVal: (i, j) => transposed ? myArr[j][i] : myArr[i][j]
}
};
var wrapped = Transposer(arr);
console.log(wrapped.getVal(1,2));
wrapped.toggle();
console.log(wrapped.getVal(1,2));
&#13;