【问题标题】:Perl: Anonymous Multi-Dimensional ArraysPerl:匿名多维数组
【发布时间】:2014-03-16 02:12:12
【问题描述】:

注意:最终解释见本文末尾。

这可能是一个非常基本的问题,但我仍在努力掌握一些有关 Perl 引用的基础知识,并且在 perldsc 页面中遇到了一些我想确认的内容。以下代码在生成数组部分中:

while ( <> ) {
   push @AoA, [ split ];
} 

显然,while 循环中的&lt;&gt; 操作一次读取一行输入。我假设此时该行通过[ ] 括号放入一个匿名数组中,我们称之为@zero。然后 split 命令将所有内容放在数组中由空格分隔的给定行中(例如,第一个单词分配给$zero[0],第二个分配给$zero[1],依此类推)。然后将@zero 的标量引用推送到@AoA

下一行输入通过&lt;&gt; 运算符传递并分配给一个全新的匿名数组(例如@one),其标量引用被推送到@AoA

一旦@AoA 被填充,我就可以使用嵌套的foreach 循环访问它的内容;第一个遍历“行”(例如for $row (@AoA)),第二个内部循环foreach 访问该特定行的列。

后者(访问所说的“列”将由dereferencing(例如for $column (@$row))完成,特定的$row被前一个“外部”foreach循环读取。
我的理解正确吗?我假设您仍然可以访问@AoA 的任何元素,就像分配它而不是匿名一样?那是$element = $AoA[8][1];

我想在这里验证我的思考过程。是否每次通过 Perl 中 autovivication 的循环部分自动声明一个唯一的匿名数组?我想这就是让我有点失望的原因。谢谢。

编辑:根据下面的cmets,我对匿名数组的理解还不清楚,所以我想再写一个描述,看看它是否符合大家的理解。

push @AoA, [split]; 语句开始,split 从$_ 中获取行并返回由whitepace 解析的list。该 list[ ] 捕获,然后返回一个数组引用。然后将该数组引用(由[ ] 创建)推送到@AoA。这是准确的回复:[ ]?下面的@krico 很好地介绍了下一步(取消引用/使用@AoA)。

最终答案/解释:根据此处的所有 cmets / 反馈,我进行了一些进一步的研究,并且测试似乎我的理解是正确的。我将在这里对其进行分解,以便其他人稍后可以轻松参考。请参阅下面@krico 的回复,了解遵循此处概述的步骤的更明确的代码表示。

while ( <> ) {
    push @AoA, [ split ];
}
  1. 一次将一行输入传递给&lt;&gt; 运算符
  2. split 函数通过$_ 获取该行并根据空格(默认)对其进行解析。
  3. split 然后返回一个 LIST。
  4. [ ] 是一个匿名数组,它为split 传递的 List 提供 perl 数据结构。
  5. push @AoA 将对匿名数组的引用作为元素 $AoA[0] 推送到其队列中(第二个匿名数组引用将被放入 $AoA1 等...)。
  6. 这将贯穿整个输入文件。完成后,@AoA 是一个 2D 数组,其中包含每个先前生成的匿名数组的引用值(标量值)。
  7. 从这一点开始,@AoA 可以适当地取消引用,以使用从输入文件中获取的基础/引用元素。默认的取消引用技术是 CIRCUMFIX(参见下面的 perlfef);但是从 5.19 开始,可以使用一种新的取消引用方法,并将在 5.20 POSTFIX 中发布。文章链接如下。

参考文献Perl References Documentation, Perl References Tutorial, Perl References Question noted by @Eli Hubert, Mike Friedman's blog post about differences between arrays and lists, Upcoming Postfix dereferencing in Perl, and Postfix dereferencing Article

【问题讨论】:

  • 您是否尝试过您所解释的内容?如果是这样,您的输出与您的预期有何不同?
  • @FlyingFrog 是的,我已经得到了我描述的结果。之前我真的没有什么期待。它有效,我只是想了解它“为什么”有效。
  • [ ITEMS ] 创建一个新的匿名数组并返回对该数组的引用。您可能会发现 perl reference tutorialthis other question 很有帮助。
  • 我想知道:使用 Perl 调试器和里面的x @AoA 不会解释一切吗? Perl 调试器非常适合检查您的数据结构。

标签: perl multidimensional-array reference


【解决方案1】:

这是怎么回事:

  1. 会将行放入默认变量 $_
  2. split 函数将读取 $_ 并返回一个数组
  3. [ ] 括号将返回一个标量,其中包含对该数组的引用
  4. 然后将该引用推入@AoA 数组

当您执行 $AoA[8][2] 时,您会隐式取消对标量的引用。与 $AoA[8]->[2] 相同。

【讨论】:

  • [] 不返回对 that 数组的引用,而是返回具有相同内容的新创建的数组。
  • Nit: split 返回一个列表,而不是一个数组。
  • @Kenosis @choroba 基于这里的一些cmets,我真的很想捕捉[ ] 作为匿名数组的使用,这首先是造成我困惑的主要原因。我已经编辑了我原来问题的结尾,以包括我迄今为止的理解。这是否符合您的目标?谢谢
【解决方案2】:

同样的代码更易读,你应该理解它。

my $line;
while ( $line = <STDIN> ) {
   my @parts = split $line;
   my $partsRef = \@parts;
   push @AoA, $partsRef;
}

现在,如果你想打印第 5 行的第二部分,你可以说。

my $ref = @AoA[4];
my @parts = @$ref;
print $parts[1];

明白了吗?

【讨论】:

  • 是的,我愿意。感谢您分解那部分。我在那里 90%。基于其他一些 cmets,我真的很想了解 [ ] 和匿名数组的使用,这首先是造成我困惑的主要原因。我已经编辑了我的问题的结尾,以包括我迄今为止的理解。这看起来对吗?
  • 根据您的输入在我的问题末尾添加了解释。谢谢。
猜你喜欢
  • 2012-05-10
  • 2011-04-24
  • 1970-01-01
  • 2019-06-12
  • 2014-11-09
  • 2011-06-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多