24566


javascriptにおける4次元配列についての質問です。以下のコードは動作します。

[code]

    var dimension4 = {
      map: [[[['4th dimension']]]],
      put: function() {
        console.log(this.map[0][0][0][0]);
      }
    };
    
    dimension4.put();
    
[/code]

ですが以下のコードは動作しません。

[code]

    var dimension4 =
     {
        map: [[[[]]]],
        ini: function()
        {
            var i, j, m, n;
            for (i = 0; i<8; i++) { for (j = 0; j<8; j++) {
                    for (m = 0; m<8; m++) { for (n = 0; n<8; n++) {
                            this.map[i][j][m][n] = '0';
                    }}
            }}
            return this.map;
        }
     };
    
     dimension4.ini();
    
[/code]

テスト環境は firefox( fire-bug ) です。  
TypeError: this.map[i][j][m] is undefined
が出力されます。何の問題もない初期化ルーチンのように私には見えます。どこに問題があるのでしょうかさっぱりわかりません。宜しくお願いします。


CC BY-SA 3.0
2016-05-04T11:13:46.447
24556
2016-05-08T18:05:15.153
2016-05-04T11:24:55.973
8000
15375
question
javascript
javascript における多次元配列の初期化について


途中のレベルの配列が未定義_undefined_ですね。美しくないですがこういうことをすればいいわけです。書き方はいろいろ試してみてください。

[code]

    var matrix4d = [],
        initializeValue = 0;
    for (var i = 0; i < 8; i++) {
      matrix4d[i] = [];
      for (var j = 0; j < 8; j++) {
        matrix4d[i][j] = [];
        for (var k = 0; k < 8; k++) {
          matrix4d[i][j][k] = [];
          for (var l = 0; l < 8; l++) {
            matrix4d[i][j][k][l] = initializeValue;
          }
        }
      }
    }
[/code]


CC BY-SA 3.0
2016-05-04T11:39:11.847
24558
2016-05-04T11:39:11.847
24556
answer


一例として、`map` 関数を使って初期化する方法を参考までに載せておきます。

[code]

    var dimension4 =
     {
        ini: function()
        {
          var arr = '0';
          for(var i=0;i<4;i++){
            arr = Array.apply(null, Array(8)).map(() => arr);
          }
          this.map = arr;
        }
     };
    
[/code]

**追記**

見直してみて気が付いたのですが、上記のコードは `shallow copy` になっています。

[code]

    dimension4.ini();
    dimension4.map[0][0][0][0] = 1;
    
    dimension4.map[0][0][1][0]
    => 1
    dimension4.map[0][1][0][0]
    => 1
    dimension4.map[1][0][0][0]
    => 1
    
[/code]

つまり、配列の `reference`(参照)をコピーしています。

jQuery や Underscore.js にはオブジェクトを完全にコピーする(deep copy)メソッドがある様ですが、それらの代わりに
`JSON.parse(JSON.stringify(arr))` を使います。

[code]

    arr = Array.apply(null, Array(8))
               .map(() => JSON.parse(JSON.stringify(arr)));
    
    dimension4.map[0][0][0][0] = 1;
    dimension4.map[0][0][1][0]
    => "0"
    dimension4.map[0][1][0][0]
    => "0"
    dimension4.map[1][0][0][0]
    => "0"
    
[/code]


CC BY-SA 3.0
2016-05-04T14:34:24.523
24566
2016-05-08T18:05:15.153
2016-05-08T18:05:15.153
24556
answer


反復処理の中で行っている下記のコード

[code]

                           this.map[i][j][m][n] = '0';
    
[/code]

のthisが示すスコープの範囲をもう一度考えてみてください。  
そのthisはグローバル領域の「map」という変数に対して、アクセスしようとしているように見えます。


CC BY-SA 3.0
2016-05-06T07:08:59.480
24601
2016-05-06T07:08:59.480
15308
24556
answer