2016-11-02 5 views
2

私は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; 
} 

を転置するために、このメソッドを書いたjavascript配列を転置しかし、これは実際には全体をコピーしたデータから、非常に非効率的です。

私が好むのは、arr[x][y]を有効にすると、arr[y][x]と表示されるフラグtransposed?を使用することです。

そして、関数transposeは、それを単にトグルします。

これはどのようにjavascriptで行うことができますか?

+0

** JavaはJavaScriptのではありません**私が知っている – chrylis

+0

、タイプミス...今プロキシに – GregA

答えて

4

代替proxiesを使用するかもしれません。それらを使用すると、配列ブラケット参照などのオブジェクトメンバアクセスを取得し、カスタマイズされた値を返すことができます。

getインデックスへのアクセスとlengthプロパティのみをサポートする単純な実装ですが、他には何もありません。本当にしたいのであれば、反復、列挙、設定、配列メソッド(joinmap、...など)をサポートするように拡張することもできますが、それを遠くにすれば実際にこれらを使用しますあなたがそうしたのと同じようにすれば、全体のパフォーマンスが向上するかもしれないので、問題は本当に価値があるかどうかということになります。配列を転置されたカウンターパートにコピーします。

とにかく、ここにある:。

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);

+0

イェーイを修正!ただし、ブラウザのサポートはまだありません:http://caniuse.com/#feat=proxy –

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));