Skip to content Skip to sidebar Skip to footer

Transposing A Javascript Array Efficiently

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=

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"