有效地转置javascript数组 [英] Transposing a javascript array efficiently
问题描述
我编写了此方法来转置javascript数组
I wrote this method to transpose a javascript array
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;
}
但是,这实际上效率很低,因为它实际上复制了整个数据.
However, this is very inefficient, since it actually copies the entire data.
我更喜欢做的是使用一个标志transposed?
,如果将其打开,它将arr[x][y]
视为arr[y][x]
.
What I prefer to do is to use a flag transposed?
that would regard arr[x][y]
as arr[y][x]
if its turned on.
然后,功能transpose
会对其进行切换.
And then, the function transpose
would just toggle it.
如何在javascript中完成此操作?
How can this be done in javascript ?
推荐答案
一种替代方法是使用代理.它们使您可以捕获对象成员的访问权限(例如数组括号引用)并返回自定义值.
An alternative might be to use proxies. They allow you to capture object member access -- such as array bracket references -- and to return a customised value.
这是一个简单的实现,仅支持对索引的get
访问和length
属性,但不支持其他功能.如果确实需要,可以将其扩展为还支持迭代,枚举,设置,数组方法(例如join
,map
,...),...等等,但是如果您走得那么远,并且会真正使用这些方法,那么问题就变成了是否值得付出所有努力,因为如果您像这样做一样,将获得更好的整体性能:将数组复制到其转置的计数器部分.
Here is a simple implementation that only supports get
access to indices, and the length
property, but nothing else. If you really wanted to, you could extend it to also support iteration, enumeration, setting, array methods (like join
, map
, ...), ...etc, but if you would go that far, and would really use these kinds of methods, then the question really becomes whether it is worth all the effort, as the total performance may be better if you do just like you did: copy the array into its transposed counter part.
无论如何,这里是:
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);
这篇关于有效地转置javascript数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!