2009-07-16 13 views
0

2次元配列をPerlで処理すると頭痛がかかります。とにかく、私の質問は次のようなものです。Perl印刷の2次元配列が正しく表示されないのはなぜですか?

@twoOneArrayなどの配列を別の配列、たとえば@twoDimArrayにプッシュしてループの次の繰り返しが開始される前にリセットされ、再度@twoDimArray新しい値のセット。私が使用してこの@twoDimArrayを印刷するとき、次のいずれか

print Dumper \@twoDimArray; 

それは出力

OUTPUTに

$VAR1 = [ 

     [ 

     'BB', 

     'AA', 

     'AA' 
     ], 
     $VAR1->[0], 
     $VAR1->[0], 
     $VAR1->[0] 
    ]; 

または使用してループ

for (my $i=0; $i<4; $i++){ 
    for (my $j=0; $j<4; $j++){ 
     print "$twoDimArray[$i][$j] \n"; 
    } 
} 

データが重複しますを提供します。

OUTPUT

行= 0 BB AAのAA

行= 1つのBB AAのAA

行= 2 BB AAのAA

行= 3 BBのAAのAA

など....

私はカント両方の出力方法がうまくいかない理由を理解してください。 @twoDimArrayを毎回(ループの次の繰り返しに移動する前、つまりプッシュ機能を使用した後に)印刷すると@twoOneArrayが挿入された場合、値はうまく再現されないようですが、一度に印刷すると上記のようになりますエラー。同様の質問はhereと聞かれましたが、それが私にとって意味があるかどうかはわかりません。助言がありますか? 2次元配列を構築するための

コード:

for ($k = 1; $k <= $counter; $k++){ 
     @twoOneArray =(); #reset it when loop starts again 
     for ($j = 0; $j <= $colsInArray; $j++){ 
     #do stuff to create @twoOneDim 
     } 
     push @twoDimArray, \@twoOneArray; 
     #if I print @twoDimArray if prints fine, with the exact values intact 
} 

print Dumper \@twoDimArray; #if I print it here it messes up 
print "\n"; 
+1

すべてのPerlプログラムの始めに常に '警告を使用する'と 'use strict;'を使用します。 –

+0

@brad:そうです。上記のコードは、実際のコードのごく一部です。なぜここに書き込まなかったのか – shubster

+1

「perldoc perldsc」のこのセクションを参照してください。ここでは、「同じメモリの場所を繰り返し参照しています」という記述があります。http://perldoc.perl.org/perldsc.html#COMMON-MISTAKESチュートリアル全体がとても良いです、perldoc perllolと同様です。 – Telemachus

答えて

10

データ:: Dumperとの出力は、あなたの問題は、アレイを印刷していないと表示されます。 Data :: Dumperはうそをつくことはありません(まれにしか)。

配列の作成に使用したコードをお知らせください。私は間違いがそのコードのどこかにあると確信しています。

UPDATE:

今、あなたは、配列を構築し、コードを追加したことを、私はあなたが悪の罠に落ちたんだことを確認:あなたはあなたの「外側」のアレイに@twoOneArrayへの参照を追加しています。しかし、参照はループのたびに常に同じになります。次のようにコードを変更してください:

for ($k = 1; $k <= $counter; $k++){ 
     my @twoOneArray; # REALLY reset it when loop starts again 
     for ($j = 0; $j <= $colsInArray; $j++){ 
      #do stuff to create @twoOneDim 
     } 
     push @twoDimArray, \@twoOneArray; 
} 

..それはうまくいくはずです。

+0

@Manni:コードが追加されました。 – shubster

+0

@Manni:私はそのエラーを決して考えなかったかもしれません。それを強調していただきありがとうございます。私は今これを永久に盗んでしまいました。あなたは私をたくさん助け、私の一日を作った!再度ありがとう:) – shubster

-3

配列の配列が必要な場合は、配列参照をプッシュする必要があります。

my @a = qw(1 2 3 4 5 6 7 8); 
my @b = qw(a b c d e f g h); 
my @aOfa; 

push(@aOfa, \@a); 
push(@aOfa, \@b); 
+0

OPは配列の参照を押して、Data :: Dumperの出力を見てください。 – derobert

4

あなたはこのような何かをやった:

@a = (1, 2, 3); 
push @b, \@a; 

@a = (2, 3, 4); 
push @b, \@a; 

# ... 

問題は、あなたが@a@b参照にプッシュしていることです。すべての参照番号は同じ@aを指しています。 Data::Dumperは、その$VAR->[0]のものでそれを伝えています。

はあなたのような何かをする必要があります。

$a = [ 1, 2, 3 ]; 
push @b, $a; 

$a = [ 2, 3, 4] ; 
push @b, $a; 

# .... 

この方法で、[ ... ]配列リファレンス構文は新しい参照される配列を毎回行います。

私はperlreututとperlrefを慎重に読むことをお勧めします。

編集:あなたのコードを投稿したことがありますが、あなたは私の壊れたコードの例です。 [ ... ]構文を使用するように変更しても問題ありません。

4

あなたの質問は他の人によって適切に回答されています。私はData::Dumperからの出力がこのような問題を見つけるのに役立つと付け加えます。配列の[1]要素は$VAR1->[0]としてダンプされます。言い換えれば、[0]要素に格納されている同じ基礎データ値への参照です。

関連する問題