【问题标题】:How do I store a 2d array in a hash in Perl?如何在 Perl 的哈希中存储二维数组?
【发布时间】:2010-12-08 20:10:45
【问题描述】:

我在 perl 中的对象中苦苦挣扎,并试图创建一个二维数组并将其存储在我的对象的哈希字段中。我知道要创建一个二维数组,我需要一个数组引用数组,但是当我尝试这样做时,我得到了这个错误: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}, []);
    }
}

知道我做错了什么吗?

【问题讨论】:

  • push @{$self-&gt;{matrix}}, []
  • 通过命令行上的perldoc perldsc 或使用perldoc.perl.org/perldsc.html 在网络上查看数据结构手册,其中包含创建和访问数据结构的示例。

标签: perl hash reference multidimensional-array perl-data-structures


【解决方案1】:

当您取消引用 $self 时,您会丢失一组额外的大括号。试试push @{$self-&gt;{matrix}}, []

如有疑问(如果您不确定是否在复杂的数据结构中引用了正确的值),请添加更多大括号。 :) 见perldoc perlreftut

【讨论】:

  • 所以我需要额外的大括号,因为 $self->{matrix} 返回一个引用?
  • 对。没有它们,您将 $self 解引用为一个数组,然后尝试在其上获取一个字段(并且由于数组可以被视为散列,这是合法的),这会产生“必须是数组(不是散列元素)”错误你所看到的。因此,您需要先使用大括号获取数组引用 $self-&gt;{matrix},然后将其取消引用到 push 的数组。
  • 附言。 perl -MO=Deparse,-p 在这里可能有助于查看您的代码是如何被解析的(即对象引用中的操作顺序),但这超出了本文的范围 :) 在此站点上搜索 [perl] deparse 以获取更多信息。
【解决方案2】:

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

这里有一个更通用的array-of-arrays函数:

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

【讨论】:

    【解决方案3】:
    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 ];
        }
    }
    

    【讨论】:

    • 我对你代码中的一些魔法感到困惑。 for(1..$seq1) 在做什么? [ (undef) X $seq2] 是什么?
    猜你喜欢
    • 2016-06-16
    • 1970-01-01
    • 1970-01-01
    • 2010-12-20
    • 2012-02-10
    • 2010-09-20
    • 1970-01-01
    • 2017-10-18
    • 2011-05-07
    相关资源
    最近更新 更多