有阵列数组的乐趣

时间:2013-05-30 17:49:25

标签: arrays perl

我是一个完整的Perl newb,但仍然无法相信我无法用我在网上阅读的所有信息来解决这个问题,但是,我已经烧了太多时间并且在这一点上遇到了阻碍。希望根据我的现实生活中的例子来学习......

好吧,我想我有一个阵列数组,像这样创建:

my @array1 = ();
my @array2 = ();
my $ctr1 = 0;
my $col;
[sql query]
while(($col)=$sth->fetchrow_array() ) {
  $array1[$ctr1]=$col;
  $ctr1++;
}

print STDERR "@array1";

##results in 10 rows, a mac address in each
##00:00:00:00:00:00 00:11:11:11:11:11 22:22:22:22:22:22 33:33:33:33:33:33 ... 

现在我再做一个查询。在循环结果时,我正在寻找那10个mac地址。当我找到一个时,我向array2添加一行,其中mac和序列号累积到该点,如下所示:

[sql query]
while(($col)=$sth->fetchrow_array() ) {
  $ctr2++;
  if( my ($matched) = grep $_ eq $col, @array1 ) {
    push( @array2, ($col,$ctr2) );
  }
}

print STDERR "@array2";

##results in 10 rows, a mac address and an integer in each
##00:00:00:00:00:00 2 00:11:11:11:11:11 24 22:22:22:22:22:22 69 33:33:33:33:33:33 82 ... 

现在很简单。我想循环遍历array2,抓取mac地址以用作sql查询的一部分。这就是问题所在。我是如此无知,以至于我正在做什么,即使我几乎工作,我无法回到那一点。无知绝对不是幸福。

当我遍历array2时,我会根据语句的不同形式获得大量错误。下面列出了我认为正确的那个以及错误消息......

my $ctr3 = 0;
foreach $ctr3 (@array2) {
  my $chkmac = $array2[$ctr3][0];    <--- gacks here with the error below - line 607
  [SQL query]


[Thu May 30 14:05:09 2013] [error] Can't use string ("00:66:55:77:99:88") as an ARRAY ref while "strict refs" in use at /path/to/test.cgi line 607.\n

我认为问题在于我的数组数组不是数组数组。如果它是,它将按照编码工作,或者我从阅读中思考......那就是说,我无法理解我正在处理的事情。这将是一个头脑清醒,我完全可以肯定,但我很难过......请帮助不多?

TIA 0

3 个答案:

答案 0 :(得分:2)

对于要使用数组引用的数组数组,例如

 push @array2, [$col, $ctr2];

访问数组引用中的元素时,您将要使用->运算符。此外,当循环遍历数组时,没有必要将索引返回到同一个数组。所以最后一部分看起来更像是:

foreach $ctr3 (@array2) {
    my $chkmac = $ctr3->[0];
    ....

答案 1 :(得分:1)

当你在那里foreach时,$ctrl3中没有索引,它将具有该值。所以你应该只需$ctrl3->[0]。注意->取消引用数组引用(@array2实际上是一个数组引用数组)。

编辑:正如AKHolland所指出的那样,@array2实际上不是数组引用的数组,尽管它应该是它。您还需要更改:

push( @array2, ($col, $ctr2) );

push( @array2, [$col, $ctr2] );

这是一个数组引用,而不是列表。此上下文中的列表只会折叠为push的常规参数,这意味着您将两个单独的字符串推送到@array2

答案 2 :(得分:0)

你是正确的,你的数组数组不是数组数组,因为在Perl中没有这样的东西。那么你有什么呢?有两种方法可以看。

首先,当你打印@array2时,你会想出一个由交替的MAC和计数组成的字符串,用空格分隔。由于空间排序表示数组元素之间的划分,我们可以推测我们得到的是异构元素的单个数组,这样元素0是MAC,元素1是计数,元素2是另一个MAC等等。

另一个观点是看@array2是如何构建的:

push( @array2, ($col,$ctr2) );

the documentation for push,我们发现push ARRAY LIST的作用是将LIST的元素附加到ARRAY的末尾。这具有将列表展平为数组的效果,使得其作为列表的原始标识丢失。您可以添加所需的所有括号,当Perl需要一个列表时,它会将所有这些括起来。

那么你如何达到你想要的效果呢? The List-of-Lists documentation有一个详细的处理,但简短的回答是你列出了数组引用。数组引用是标量,因此是数组中的合法元素。但是他们保留了他们作为数组引用的标识!

匿名数组引用构造函数是方括号[]。为了将包含元素$col$ctr2的数组引用推送到@array2的末尾,您只需执行此操作:

push( @array2, [$col, $ctr2] );

您为访问数组引用的特定元素而编写的代码现在可以正常工作。但是,既然我已经就这个主题撰写了很多段落,那么让我先解释一下最初的错误,以及如何更改push语句会突然发挥作用。

表达式$array2[$ctr3][0]有时会写为$array2[$ctr3]->[0],以澄清它实际上在做什么。它的作用是取$array2[$ctr3]的值并将其视为数组引用,取其0元素。如果我们将$ctr3视为0(因为它位于循环的顶部),$array2[$ctr3]的值是第一个元素00:00:00:00:00:00。然后,当您随后要求Perl将00:00:00:00:00:00视为数组引用时,Perl会死,因为它不知道如何将字符串视为数组引用。

相反,$array2[$ctr3]的值是一个数组引用,因为这是你在构造它时推送到@array2的内容,Perl能够按你的要求去做,取消引用数组引用并查看元素结果数组的0,其值恰好为00:00:00:00:00:00