• ベストアンサー

2次元配列のコピーについて

2次元配列のコピーについて質問があります。 $Aが元の2次元配列、$Bがコピー先だとして、 ${$A}[0..N][0..N]に値が入っているとします。 ここで、$Bの代入を、$B=$Aとやってしまうと、$Aと$Bが連動してしまいます。 ($Bが書き換わったのに$Aも書き換わる) これはなぜなのでしょうか。 また、$Bの代入を、配列を走査して foreach (0.. $#{$A}) {  my ($i) = $_;  foreach (0.. $#{${$A}[$i]})  {   my ($j) = $_;   ${$B}[$i][$j] = ${$A}[$i][$j];  } } とすれば問題ないのですが、あまりスマートだと思えません。 もっとスマートにコピーする方法はありますか?

質問者が選んだベストアンサー

  • ベストアンサー
  • osamuy
  • ベストアンサー率42% (1231/2878)
回答No.2

元の$aが配列へのリファレンスなので、その$aを代入した$bも同じ配列へのリファレンスになるのは当然。 リファレンスのみをコピーする事をshallow copyと言い、実体までコピーするdeep copyとの違いを意識する必要があります。ここらへん、Perlに限らず、CやJavaでも出現する古典的な話題ですので、検索するといろいろ参考になるサイトが見つかると思います。 基本的に自分でコピーの処理を記述する必要がありますが、モジュールStorableのdcloneですますという手もあります。 詳しくはperldoc Storableをご覧下さい。

w00d0st0k
質問者

お礼

リファレンスを意識してませんでした^^;; 勉強し直します…

その他の回答 (2)

  • thatsthat
  • ベストアンサー率55% (15/27)
回答No.3

ベストかどうかは分かりませんが、  @b=map{[@{$_}]} @{$a} くらいでしょうか。 @bと書いた通り、上のbは配列です。 bも参照の方が良いなら、適宜[~]等して下さい。

w00d0st0k
質問者

お礼

ありがとうございます。 mapとかgrepとかの使い方も勉強します…

  • masaota56
  • ベストアンサー率41% (58/139)
回答No.1

$Aと$Bが連動するのは、リファレンス(Cで言うポインタのようなもの)をコピーしているからです。デリファレンス(実態参照)してコピーしないといけません。 今手元にPerlが無いので確認できず申し訳ないのですが、 @$B = @$A で上手くいかないでしょうか。 http://72.14.235.104/search?q=cache:kabocha.org/jelfe/07/20.html+perl+%E3%83%87%E3%83%AA%E3%83%95%E3%82%A1%E3%83%AC%E3%83%B3%E3%82%B9

w00d0st0k
質問者

お礼

ありがとうございます、ちょっと試してみます。