Как мне сохранить 2d массив в хэше в Perl? - PullRequest
1 голос
/ 21 октября 2009

Я борюсь с объектами в Perl, и пытаюсь создать 2-мерный массив и сохранить его в хэш-поле моего объекта. Я понимаю, что для создания 2d-массива мне нужен массив ссылок на массивы, но когда я пытаюсь это сделать, я получаю эту ошибку: Type of arg 1 to push must be array (not hash element) Конструктор работает нормально, а set_seqs работает нормально, но моя подпрограмма create_matrix выдает эти ошибки.

Вот что я делаю:

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}, []);
    }
}

Есть идеи, что я делаю не так?

Ответы [ 3 ]

4 голосов
/ 21 октября 2009

Вам не хватает дополнительного набора скобок при разыменовании $ self. Попробуйте push @{$self->{matrix}}, [].

Если вы сомневаетесь (если вы не уверены, что имеете в виду правильное значение в сложной структуре данных), добавьте больше фигурных скобок. :) См. perldoc perlreftut .

3 голосов
/ 21 октября 2009

Perl является очень выразительным языком. Вы можете сделать это все с заявлением ниже.

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

Это гольф? Возможно, но это также позволяет избежать взлома с привередливым push прототипом Я взрываю утверждение ниже:

$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.

У меня есть стандартная подпрограмма для создания таблиц:

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

А вот более обобщенная функция массива массивов:

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;
}
2 голосов
/ 21 октября 2009
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 ];
    }
}
...