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