【问题标题】:How do I access arrays of array in perl?如何在 perl 中访问数组的数组?
【发布时间】:2013-03-07 08:48:08
【问题描述】:

您好,我有一个数组作为 myarray。我想创建一个列表作为 '1 2 3' 加入第一个子数组。我的字符串正在打印我想的内存位置而不是列表。任何帮助将不胜感激。

@myarray = [[1,2,3],[4,5,6],[7,8,9]];
for (my $i=0; $i < @myarray; $i++) {
my @firstarray = $myarray[$i];
my $mystring = join("", @firstarray);
print "My string ".$mystring . ". "\n";
}

【问题讨论】:

  • 了解 Perl 引用和取消引用。与流行的看法相反,它们几乎完全不同于 C 风格的指针,而且在你的示例中你正在用它们做一些奇怪的事情。下面的 Perl 教程给出了我所知道的主题的最简洁的处理:qntm.org/files/perl/perl.html
  • use warnings; -- 这会提醒您注意 @myarray 的奇怪初始化
  • 对于参考我更喜欢核心文档perldoc perlreftut。它使引用更容易理解。

标签: arrays perl join multidimensional-array perl-data-structures


【解决方案1】:

您必须通过@{ ... } 取消引用内部数组引用。此外,不要将[...] 用于顶部结构 - 使用普通括号(方括号创建数组引用,而不是数组)。您的print 行的连接也存在问题:

@myarray = ( [1,2,3], [4,5,6], [7,8,9] );
for (my $i=0; $i < @myarray; $i++) {
    my @firstarray = @{ $myarray[$i] };
    my $mystring = join("", @firstarray);
    print "My string " . $mystring . ".\n";
}

【讨论】:

  • @ikegami:我只是尽量接近原始代码。
【解决方案2】:

您应该使用Data::Dumper 模块,这样可以帮助您了解如何解析数据结构:

print Dumper \@myarray; # force passing array as ref
$VAR1 = [
          [
            [
              1,
              2,
              3
            ],
            [
              4,
              5,
              6
            ],
            [
              7,
              8,
              9
            ]
          ]
        ];

但是使用@sigil(数组)来存储ARRAY ref很奇怪,$ sigil(标量)在大多数情况下都用于此目的。 (reference 就像 C 指针:指向内存单元的地址。所以它是一个简单的字符串,不需要其他东西来存储它)

然后,您需要使用-&gt; 运算符取消引用

例如:

$ perlconsole
Perl Console 0.4

Perl> my $arrayref = [[1,2,3],[4,5,6],[7,8,9]];

Perl> print join "\n", @{ $arrayref->[2] }
7
8
9

【讨论】:

    【解决方案3】:

    你实际上有一个数组数组。

    • 外部数组有一个元素,即对数组的引用。
      $myarray[0]
    • 引用的数组包含三个元素,每个元素都是对数组的引用。
      $myarray[0][0..2]
    • 每个引用的数组都有三个元素,三个数字。
      $myarray[0][0..2][0..2]

    你想要

    my @aoa = ([1,2,3],[4,5,6],[7,8,9]);
       ^       ^       ^       ^
       |        \------+------/
       |            3 inner
    1 outer
    
    $aoa[$i][$j]
    
    for my $inner (@aoa) {
       print(join(', ', @$inner), "\n");
    }
    

    my $aoa = [[1,2,3],[4,5,6],[7,8,9]];
              ^^       ^       ^
              | \------+------/
              |      3 inner
           1 outer
    
    $aoa->[$i][$j]
    
    for my $inner (@$aoa) {
       print(join(', ', @$inner), "\n");
    }
    

    【讨论】:

    • 为什么它是“数组的数组”?我看到一个外部数组或三个内部一维数组
    • @amphibient,因为你有 3 个数组被一个数组的元素引用,一个数组的元素被一个数组的元素引用。那是 5 个数组,而不是 4 个。正如我所展示的,计算 my @[]。请记住,[...] 基本上是 do { my @a = (...); \@a }
    • 但是如果你有 3 个内部和 1 个外部,那就是 4 个数组,不是吗?此外,我只是将其视为一个简单的AoA [3][3]
    • @amphibient,是的,如果你有 3 个内部和一个外部,那将是 4。因为他有 5 个(一个用 my 创建,4 个用 [] 创建),他没有t 有 3 个内部和 1 个外部。这也可以通过Dumper(\@myarray) 看到。
    • 啊,好的——所以你是说,按照他的声明方式,他有 5 个,而他应该正确有 4 个
    【解决方案4】:

    您需要更改初始化数组的方式,以便 () 用于外部数组边界,[] 用于内部数组,这意味着它们被声明为引用,稍后需要将其转换为用于处理的原生数组格式 (my @subarray = @{$myarray[$i]};)

    my @myarray = ([1,2,3], [4,5,6], [7,8,9]);
    
    for (my $i=0; $i < @myarray; $i++) 
    {
        my @subarray = @{$myarray[$i]};
        my $subarrayStr = join("", @subarray);
        print $i.". Subarray Str = ".$subarrayStr."\n";
    }
    

    【讨论】:

      【解决方案5】:
      $myarray = [[1,2,3],[4,5,6],[7,8,9]];
      printf "My string %s\n", join(" ", @{$myarray->[0]});
      

      [[1,2,3],[4,5,6],[7,8,9]] 返回对列表列表的引用,而不是列表。

      @ 更改为 $ ,使 $myarray 成为变量。

      @{$myarray-&gt;[0]} 将取消引用第一个子列表并返回您可以使用的列表。

      打印所有三个列表:

      $myarray = [[1,2,3],[4,5,6],[7,8,9]];
      map{printf "My string %s\n", join(" ",@{$_})} @{$myarray};
      

      【讨论】:

        猜你喜欢
        • 2013-03-08
        • 1970-01-01
        • 2013-08-21
        • 2023-03-08
        • 1970-01-01
        • 2014-10-13
        • 2016-12-12
        • 1970-01-01
        相关资源
        最近更新 更多