如何在perl中创建多维数组?

时间:2011-06-21 13:20:03

标签: perl

我用这种方式创建了一个多维数组:

#!/usr/bin/perl
use warnings;
use strict;

my @a1 = (1,2);
my @a2 = (@a1,3);

但事实证明我仍然有一个一维数组...

perl的正确方法是什么?

6 个答案:

答案 0 :(得分:9)

你得到一维数组,因为数组@a1在parens中扩展。所以,假设:

my @a1 = (1,2);
my @a2 = (@a1,3);

然后你的第二个陈述相当于my @a2 = (1,2,3);

创建多维数组时,您有几个选择:

  1. 直接分配每个值
  2. 取消引用现有数组
  3. 插入参考
  4. 第一个选项基本上是$array[0][0] = 1;不是很令人兴奋。

    第二个是这样做:my @a2 = (\@a1, 3);请注意,这会引用数组@a1的命名空间,因此如果您稍后更改@a1@a2中的值也会改变。并不总是推荐选项。

    第二个选项的变体是这样做的:my @a2 = ([1,2], 3);括号将创建一个匿名数组,它没有命名空间,只有一个内存地址,并且只存在于@a2内。

    第三个选项,有点模糊,正在执行此操作:my $a1 = [1,2]; my @a2 = ($a1, 3);它将完成与2完全相同的操作,只有数组引用已经在标量变量中,称为$a1。< / p>

    注意分配给数组时()[]之间的区别。括号[]创建一个匿名数组,它返回一个数组引用作为标量值(例如,可以由$a1$a2[0]保存)。

    另一方面,Parens确实什么都不做,除了改变运算符的优先级。

    考虑这段代码:

    my @a2 = 1, 2, 3;
    print "@a2";
    

    这将打印1。如果您use warnings,您还会收到警告,例如:Useless use of a constant in void context。基本上会发生什么:

    my @a2 = 1; 
    2, 3;
    

    因为逗号(,)的优先级低于等号=。 (参见perldoc perlop

    中的“运算符优先级和相关性”

    parens做的只是在列表中将=,以及组1,2,3的默认优先级否定,然后传递给@a2

    因此,简而言之,括号[]有一些神奇之处:它们创建了匿名数组。 Parens ()只是改变了优先级,就像在数学中一样。

    文档中有很多内容需要阅读。这里曾经有人向我展示了一个非常好的解除引用链接,但我不记得它是什么。在perldoc perlreftut中,您将找到有关参考的基本教程。在perldoc perldsc中,您将找到有关数据结构的文档(感谢Oesor提醒我)。

答案 1 :(得分:6)

我建议通过perlreftut, perldsc and perllol,最好是在同一天,最好使用Data::Dumper来打印数据结构。

教程相互补充,我认为它们会更好地结合起来。可视化数据结构帮助我很多人相信他们实际工作(认真)并看到我的错误。

答案 2 :(得分:4)

数组包含标量,因此您需要添加引用。

my @a1 = (1,2);
my @a2 = (\@a1, ,3);

您需要阅读http://perldoc.perl.org/perldsc.html

答案 3 :(得分:2)

  

最重要的是要理解   关于中的所有数据结构   Perl - 包括多维   数组 - 即使他们可能   否则,Perl @ARRAY 和   %HASH es都在内部   一维的。他们只能持有   标量值(表示字符串,   数字或参考)。他们不能   直接包含其他数组或   哈希,而是包含引用   到其他阵列或哈希。

现在,因为顶级只包含引用,如果你尝试使用简单的print()函数打印出你的数组,你会得到看起来不太好的东西,如下所示:

    @AoA = ( [2, 3], [4, 5, 7], [0] );
    print $AoA[1][2];
    7
    print @AoA;
    ARRAY(0x83c38)ARRAY(0x8b194)ARRAY(0x8b1d0)

那是因为Perl不会(永远)隐式取消引用您的变量。如果你想得到一个引用引用的东西,那么你必须自己使用前缀类型指示符,如${$blah} , @{$blah} , @{$blah[$i]},或者后缀指针箭头,如$a->[3] , $h->{fred},甚至{ {1}}

来源:perldoc


现在回答你的问题。这是你的代码:

$ob->method()->[3]

请注意,数组包含标量值。因此,您必须使用引用,并且可以在要引用的数组名称之前使用my @a1 = (1,2); my @a2 = (@a1,3); 关键字添加引用。

像这样:

\

答案 4 :(得分:1)

内部数组应该是外部数组中的标量引用:

my @a2 = (\@a1,3); # first element is a reference to a1
print ${$a2[0]}[1]; # print second element of inner array

答案 5 :(得分:0)

这是2D数组的简单示例,如

my $AoA=undef;
for(my $i=0;$i<3;$i++) {
   for(my $j=0;$j<3;$j++) {
      $AoA->[$i]->[$j] = rand(); #assign some value
   }
}