53196


JavaScriptでの配列のコピー及び加工についてかれこれ丸一日悩んでいて、どうしても分からない事があったので質問します。

＊やりたいこと＊  
ざっくり言うと受け取った配列から余因子行列を作成することです。詳しくは以下

  1. 配列(A)を受け取る(例えば今回は二次元配列に3x3行列が格納されているものとします)
  2. Aの2行目以降を新しい配列(D)にコピー
  3. 繰返し処理でDのそれぞれの要素(今回は二行目と三行目)からi番目の要素を削除
  4. Dを出力
  5. 2に戻る

入力: A = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]  
出力: 1回目: [[5, 6], [8, 9]]  
2回目: [[4, 6], [7, 9]]  
3回目: [[4, 5], [7, 8]]

現段階で書いたコードは以下の通りです。

[code]

    this.dimention = 3
    arrayMatrix = [[1, 2 , 3], [4, 5, 6], [7, 8, 9]]
    for (var i = 0; i < this.dimention; i++) {
      var Dij = new Array(this.dimention)
      for (var k = 0; k < this.dimention; k++) {
        Dij[k] = arrayMatrix[k]
      }
      Dij = Dij.slice(1)
      for (var j = 0; j < this.dimention - 1; j++) {
        Dij[j].splice(i, 1)
      }
      console.log(Dij)
    }
    
[/code]

まずDを使い回すためにコピーしているのですが要素を削除すると元の配列にも影響し次のDの作成ができなくなってしまいます。  
そのためシャローコーピでなくコードの様なディープコピーを色々試してみたのですがどうしても元の配列の要素も削除されてしまいます。  
そもそも実装方法でもっといいものがあるような気がしてならないです。

解決方法でなくても何か参考になることがあれば是非教えて頂きたいです。

追記  
以下の方法で現状目的は達成されました。これでも3重ループになってしまっているので、他のいい実装方法があれば教えて頂きたいです。

[code]

    dimention = 3
    arrayMatrix = [[1, 2 , 3], [4, 5, 6], [7, 8, 9]]
    for (var i = 0; i < this.dimention; i++) {
            var Dij = []
            for (var k = 0; k < this.dimention - 1; k++) {
              Dij.push([])
              for (var l = 0; l < this.dimention; l++) {
                if (l !== i) {
                  Dij[k].push(arrayMatrix[k + 1][l])
                }
              }
            }
          }
    
[/code]


CC BY-SA 4.0
2019-03-04T15:24:38.657
53195
2021-12-25T09:06:01.753
2021-12-25T09:06:01.753
32986
question
javascript array
JavaScriptでの配列のコピー及び加工


「コードの様なディープコピー」とありますが、あなたのコードは全くディープコピーになっていません。

  * 単なる代入 ⇒ コピーにさえならない
  * 一番外側の配列だけコピー ⇒ シャローコピー (あなたのコード)
  * 内側の配列もコピーを作る ⇒ ディープコピー

(この回答を書くためにネット上を検索したら、あまりにも多くの記事で「シャローコピー」「ディープコピー」の意味を間違っていたのでびっくりしましたが…。)

JavaScriptの配列のコピーには色々なやり方があるのでディープコピーの方法もいろいろですが、できるだけ上側のあなたのコードを活かすなら、

この部分:

[code]

            var Dij = new Array(this.dimention)
            for (var k = 0; k < this.dimention; k++) {
                Dij[k] = arrayMatrix[k]
            }
    
[/code]

をこんな風に書き換えてみてください。

[code]

            var Dij = new Array(this.dimention)
            for (var k = 0; k < this.dimention; k++) {
                Dij[k] = arrayMatrix[k].concat() //<- 
            }
    
[/code]

あるいはこの4行をまとめてこんな風に書いてしまうこともできます。

[code]

            var Dij = arrayMatrix.map(innerArr => innerArr.concat());
    
[/code]

上に書いたようにいろいろな方法がありますが、「内側の配列もコピーを作る」と言うことをしていないのに「ディープコピー」と呼ぶのは間違っている、と言うのは覚えておいてください。


CC BY-SA 4.0
2019-03-04T18:03:30.557
53196
2019-03-04T18:03:30.557
13972
53195
answer