1

Je me bats à travers des objets en perl, et j'essaie de créer un tableau 2D et de le stocker dans un champ de hachage de mon objet. Je comprends que pour créer un tableau 2d j'ai besoin d'un tableau de références à des tableaux, mais quand j'essaie de le faire, je reçois cette erreur: Type of arg 1 to push must be array (not hash element) Le constructeur fonctionne très bien, et set_seqs fonctionne très bien, mais mon create_matrix sub jette ces erreurs.Comment stocker un tableau 2d dans un hachage en Perl?

Voici ce que je fais:

sub new { 
    my ($class) = @_; 
    my $self = {}; 
    $self->{seq1} = undef; 
    $self->{seq2} = undef; 
    $self->{matrix} =(); 
    bless($self, $class); 
    return $self; 
} 
sub set_seqs { 
    my $self = shift; 
    $self->{seq1} = shift; 
    $self->{seq2} = shift; 
    print $self->{seq1}; 
} 

sub create_matrix { 
    my $self = shift; 
    $self->set_seqs(shift, shift); 
    #create the 2d array of scores 
    #to create a matrix: 
    #create a 2d array of length [lengthofseq1][lengthofseq2] 
    for (my $i = 0; $i < length($self->{seq1}) - 1; $i++) { 
     #push a new array reference onto the matrix 
     #this line generates the error 
     push(@$self->{matrix}, []); 
    } 
} 

Toute idée de ce que je fais mal?

+0

'pousser @ {$ self -> {matrix}}, [] ' –

+2

Consultez le livre de recettes Data Structures via' perldoc perldsc' sur la ligne de commande ou sur le web avec http://perldoc.perl.org/perldsc.html C'est plein d'exemples pour créer et accéder aux structures de données. – daotoad

Répondre

4

Il vous manque un jeu supplémentaire d'accolades lorsque vous dérérez $ self. Essayez push @{$self->{matrix}}, []. En cas de doute (si vous ne savez pas si vous faites référence à la bonne valeur dans une structure de données compliquée), ajoutez d'autres accolades. :) Voir perldoc perlreftut.

+1

+1 bonne suggestion pour l'avenir. – Axeman

+0

J'ai donc besoin de l'ensemble supplémentaire d'accolades car $ self -> {matrix} renvoie une référence? – jergason

+1

Droite. Sans eux, vous seriez déréférencer $ self comme un tableau et ensuite essayer d'obtenir un champ sur cela (et puisque les tableaux peuvent être traités comme des hachages, c'est légal), ce qui donne l'erreur "must be array (pas hash)" que tu vois. Donc, vous avez besoin des accolades pour obtenir le arrayref '$ self -> {matrix}' d'abord, puis déréférencer cela vers un tableau pour 'push'. – Ether

2
sub create_matrix { 
    my($self,$seq1,$seq2) = @_; 
    $self->set_seqs($seq2, $seq2); 

    #create the 2d array of scores 
    #to create a matrix: 
    #create a 2d array of length [$seq1][$seq2] 
    for(1..$seq1){ 
     push @{$self->{matrix}}, [ (undef) x $seq2 ]; 
    } 
} 
+0

Je suis confus au sujet de la magie dans votre code. Quel est le but de (1 .. $ seq1)? Qu'est-ce que [(undef) X $ seq2]? – jergason

3

Perl est un très expressive, la langue. Vous pouvez le faire tous avec la déclaration ci-dessous.

$self->{matrix} = [ map { [ (0) x $seq2 ] } 1..$seq1 ]; 

Est-ce golf? Peut-être, mais aussi évite de déblayer avec le prototype push finicky. J'exploser la déclaration ci-dessous:

$self->{matrix} = [  # we want an array reference 
    map {    # create a derivative list from the list you will pass it 
     [ (0) x $seq2 ] # another array reference, using the *repeat* operator 
         # in it's list form, thus creating a list of 0's as 
         # long as the value given by $seq2, to fill out the 
         # reference's values. 
    } 
    1..$seq1    # we're not using the indexes as anything more than 
         # control, so, use them base-1. 
];      # a completed array of arrays. 

J'ai un sous-programme standard pour faire des tableaux:

sub make_matrix { 
    my ($dim1, $dim2) = @_; 
    my @table = map { [ (0) x $dim2 ] } 1..$dim1; 
    return wantarray? @table : \@table; 
} 

Et voici un tableau-de-tableaux fonction plus générale:

sub multidimensional_array { 
    my $dim = shift; 
    return [ (0) x $dim ] unless @_; # edge case 

    my @table = map { scalar multidimensional_array(@_) } 1..$dim; 
    return wantarray ? @table : \@table; 
} 
Questions connexes