1

我正在苦苦尋覓perl中的對象,並試圖創建一個2d數組並將其存儲在我的對象的散列字段中。我知道創建一個2d數組我需要一個數組引用數組,但是當我嘗試這樣做時,我得到這個錯誤:Type of arg 1 to push must be array (not hash element)構造函數工作正常,並且set_seqs工作正常,但我的create_matrix子正在拋出這些錯誤。如何將二維數組存儲在Perl中的散列中?

下面是我在做什麼:

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

什麼我做錯了任何想法?

+0

'推@ {$ self - > {matrix}},[]' – 2009-10-21 18:59:12

+2

通過命令行或網絡上的'perldoc perldsc'用http://perldoc.perl.org/perldsc.html 查看Data Structures Cookbook它充滿了創建和訪問數據結構的例子。 – daotoad 2009-10-21 19:29:25

回答

4

當您取消引用$ self時,您錯過了一組額外的大括號。試試push @{$self->{matrix}}, []

如有疑問(如果您不確定是否在複雜的數據結構中引用了正確的值),請添加更多大括號。 :)見perldoc perlreftut

+1

+1好的未來建議。 – Axeman 2009-10-21 19:24:17

+0

所以我需要額外的大括號,因爲$ self - > {matrix}返回一個引用? – jergason 2009-10-21 20:08:51

+1

對。沒有它們,你會將$ self作爲一個數組解除引用,然後試圖獲得一個字段(因爲數組可以被視爲哈希,這是合法的),這會產生「必須是數組(不是散列元素)」的錯誤你看到了。所以你需要大括號來首先獲取arrayref'$ self - > {matrix}',然後將其解除引用到'push'的數組。 – Ether 2009-10-21 20:20:34

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

我對你的代碼中的一些魔法感到困惑。 for(1 .. $ seq1)在做什麼?什麼是[(undef)X $ seq2]? – jergason 2009-10-21 19:56:19

3

Perl是一種非常表現語言。你可以用下面的語句來做到這一點。

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

這是高爾夫嗎?也許吧,但它避免與finkedy 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; 
}