Transposing A Javascript Array Efficiently
Solution 1:
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.
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.
Anyway, here it is:
var a = [ [1,2,3],
[4,5,6] ];
a.transposed = newProxy(a, {
get: (arr, col) =>
+col >= 0 ? newProxy({ 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);
Solution 2:
I don't think you can override the []
of an array, and I also believe it would introduce many nasty bugs if you could.
A quick solution might be to write a utility function that swaps the arguments:
var arr = [
['A', 'B', 'C'],
[1, 2, 3],
['x', 'y', 'z']
];
// Using a short, pure function:vargetVal = (arr, i, j) => arr[i][j];
vargetTransposed = (arr, i, j) => getVal(arr, j, i);
console.log(getVal(arr, 1,2));
console.log(getTransposed(arr, 1,2));
// Using a "class"varTransposer = 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));
Post a Comment for "Transposing A Javascript Array Efficiently"