2009-07-16 6 views
0

La manipulation de tableaux bidimensionnels en Perl me donne mal à la tête. Quoi qu'il en soit, ma question est la suivante:Pourquoi le tableau à deux dimensions de Perl n'est-il pas correctement imprimé?

J'ai une boucle qui pousse un tableau, disons @twoOneArray, dans un autre tableau, disons @twoDimArray, puis est réinitialisé avant que la prochaine itération de la boucle commence, puis est de nouveau poussé dans @twoDimArray avec un nouvel ensemble de valeurs. Lorsque j'imprime cette @twoDimArray en utilisant soit:

print Dumper \@twoDimArray; 

donne la sortie

SORTIE

$VAR1 = [ 

     [ 

     'BB', 

     'AA', 

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

ou en utilisant des boucles

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

les données se reproduit.

SORTIE

Row = 0 BB AA AA

Row = 1 BB AA AA

Row = 2 BB AA AA

Row = 3 BB AA AA

et ainsi de suite ....

Je ne peux pas comprendre pourquoi les deux les moyens de sortie vont mal. Si j'imprime @twoDimArray à chaque fois (avant de passer à la prochaine itération de la boucle, ie après avoir utilisé la fonction push) @twoOneArray est inséré, alors les valeurs semblent être bonnes et ne pas se répéter, mais l'imprimer en une seule fois semble donner Erreur. Question similaire a été demandé here mais je ne suis pas sûr si cela a un sens pour moi. Aucune suggestion?

Code pour construire tableau 2D:

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

Toujours 'use warnings 'et' use strict; 'au début de tous les programmes Perl. –

+0

@brad: Oui. Le code ci-dessus est une infime partie du code actuel. alors c'est pourquoi ne l'a pas écrit ici. – shubster

+1

Voir cette section de 'perldoc perldsc', la partie où il décrit" prendre une référence au même emplacement de mémoire à plusieurs reprises ": http://perldoc.perl.org/perldsc.html#COMMON-MISTAKES Tout le tutoriel est très bon , comme le 'perldoc perllol' – Telemachus

Répondre

10

La sortie de données :: Dumper me dit que votre problème n'imprime pas le tableau. Données :: Dumper ne ment jamais (ou seulement rarement).

Veuillez nous montrer le code que vous avez utilisé pour construire la matrice. Je suis sûr que cette erreur est dans ce code quelque part.

MISE À JOUR:

Maintenant que vous avez ajouté le code qui construit le tableau, je vois que vous êtes tombé dans un piège mal: Vous ajoutez la référence à @twoOneArray à votre tableau « extérieur ». Mais la référence sera toujours la même à chaque fois dans votre boucle. Changez votre code comme ceci:

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

.. et cela devrait fonctionner.

+0

@Manni: Code ajouté. – shubster

+0

@Manni: Je n'aurais jamais pensé à cette erreur. Merci beaucoup pour l'avoir souligné. Je l'avais désengorgé pour toujours maintenant. Tu m'as beaucoup aidé et fait ma journée! Merci encore :) – shubster

-3

Si vous voulez un tableau de tableaux, vous devez appuyer sur des références de tableau, par ex.

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

L'OP pousse des références de tableau, regardez la sortie Data :: Dumper. – derobert

4

Vous avez fait quelque chose comme ceci:

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

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

# ... 

Le problème est que vous poussez sur @b une référence -@a. Toutes les références pointent vers le même @a. Data::Dumper vous dit cela avec sa chose $VAR->[0].

Vous devez faire quelque chose comme:

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

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

# .... 

De cette façon, la syntaxe [ ... ] arrayref fera un nouveau tableau référencé à chaque fois.

Je suggère une lecture attentive de perlreftut et perlref.

éditer: Je vois que vous avez posté votre code, et oui, vous faites mon exemple de code cassé. Changez pour utiliser la syntaxe [ ... ] et tout ira bien.

4

Votre question a reçu une réponse satisfaisante par d'autres. J'ajouterais que la sortie de Data::Dumper est utile pour repérer de tels problèmes: l'élément [1] de votre tableau est envoyé comme $VAR1->[0] - en d'autres termes, il s'agit d'une référence aux mêmes valeurs de données sous-jacentes stockées dans l'élément [0].

Questions connexes