【问题标题】:Perl - Push into arrays using variable references versus using variable copiesPerl - 使用变量引用与使用变量副本推入数组
【发布时间】:2011-04-23 13:10:20
【问题描述】:

问题:为什么我不能将元素推送到一个二维数组中,该数组位于解析 SQL 结果集的 while 循环内?

我需要一些帮助来了解为什么会发生这种情况。数据存储到二维数组的方式可以有多种方式,但就我的目的而言,我需要使用 push 方法。

下面是一些有效的代码:

my @tt = (0,1,2,3);
my @t;
push (@t,\@tt);
print "[0][0]:".$t[0][0]."\n";
print "[0][1]:".$t[0][1]."\n";
print "[0][2]:".$t[0][2]."\n";
print "[0][3]:".$t[0][3]."\n";
@tt = (4,5,6,7);
push (@t,\@tt);
print "[1][0]:".$t[1][0]."\n";
print "[1][1]:".$t[1][1]."\n";
print "[1][2]:".$t[1][2]."\n";
print "[1][3]:".$t[1][3]."\n";

输出是:

-------------------------
[0][0]:0
[0][1]:1
[0][2]:2
[0][3]:3
[1][0]:4
[1][1]:5
[1][2]:6
[1][3]:7


这是我遇到的问题

我正在运行一些 SQL 来构建一个包含 X 列数的结果集。要将数据存储到我的数组中,我想我可以使用与上面相同的语法:

while (@results=$sth->fetchrow_array())
{
    push(@stu_pool,\@results);
} 

我测试了 SQL 并检查了结果集,所以问题与此无关。我也回到了长期的方法,这让我得到了我想要的最终结果。我没有使用push(@stu_pool,\@results);,而是在循环中使用了这段代码:

$stu_pool[$index][0] = $results[0];
$stu_pool[$index][1] = $results[1];
$stu_pool[$index][2] = $results[2];
$stu_pool[$index][3] = $results[3];
$stu_pool[$index][4] = $results[4];
$stu_pool[$index][5] = $results[5];
$stu_pool[$index][6] = $results[6];
$index++;

那么是什么阻止我将元素推入这个数组?它适用于第一个示例,但是当我尝试打印出元素时,它们都是空白的。我正在使用的代码:

print "[0][0]:".$stu_pool[0][0]."\n";
print "[0][1]:".$stu_pool[0][1]."\n";
print "[0][2]:".$stu_pool[0][2]."\n";
print "[0][3]:".$stu_pool[0][3]."\n";
print "[1][0]:".$stu_pool[1][0]."\n";
print "[1][1]:".$stu_pool[1][1]."\n";
print "[1][2]:".$stu_pool[1][2]."\n";
print "[1][3]:".$stu_pool[1][3]."\n";

重复:

为什么 push 方法在 while 循环中不起作用?

【问题讨论】:

  • 我将其写为评论,因为它不是您问题的答案,但仍然必须说:将同一行复制粘贴 6 次是个坏主意。使用循环。帮自己一个忙,看看这个演讲:video.google.com/videoplay?docid=-4037440245833870135
  • 我只是把它作为一个例子。它简单易读,不会添加额外的元素供人们检查作为问题的可能原因
  • stu_pool的第二维包含的每个数组除了包含7个元素
  • 好吧,猴子看猴子做什么。当人们看到这样的代码时,他们会编写这样的代码。

标签: arrays perl reference copy push


【解决方案1】:

让我稍微改变一下你的第一个例子。

my @tt = (0,1,2,3);
my @t;
push (@t,\@tt);
@tt = (4,5,6,7);
push (@t,\@tt);
print "[0][0]:".$t[0][0]."\n";
print "[0][1]:".$t[0][1]."\n";
print "[0][2]:".$t[0][2]."\n";
print "[0][3]:".$t[0][3]."\n";
print "[1][0]:".$t[1][0]."\n";
print "[1][1]:".$t[1][1]."\n";
print "[1][2]:".$t[1][2]."\n";
print "[1][3]:".$t[1][3]."\n";

输出:

[0][0]:4
[0][1]:5
[0][2]:6
[0][3]:7
[1][0]:4
[1][1]:5
[1][2]:6
[1][3]:7

您没有将@tt 复制到@t。您将对变量@tt 的引用放入@t。因此,当@tt 发生其他事情时,它也会在通过@t 获取时发生变化。要真正制作副本,您需要 push(@t,[@tt])@{$t[$i]} = @tt(如果 $i 是适当的索引变量)。

或者对于另一个例子,试试push(@stu_pool, [@results]);

【讨论】:

  • 感谢您的澄清 - 我不知道 `` 做了什么。当我试图找出如何在 Perl 中做 2d 数组时,我从网上看到的一个示例中选择了它——另外,感谢您帖子中的最后一行。这就是我真正想要的
  • 我是否也可以使用 foreach(@results) 和 $_ 变量的某种组合来获得相同的效果?
  • @CheeseConQueso:我不完全确定你的意思,但我怀疑答案是“是的,但是为什么在你不需要的时候引入另一个循环?”
  • 好吧,那只调用一次fetchrow_array。小心:@_ 不是$_。你读过 perldoc perllol 吗? [perldoc.perl.org/perllol.html]
  • 实际上,现在我再看一遍,我建议在 perllol 之前阅读 perlreftut [ perldoc.perl.org/perlreftut.html ]。
【解决方案2】:

只有一个@results - 你让@stu_pool 的每个元素都引用同一个@results,它(最后一次检查循环条件)最终将被设置为包含() .

您想要添加mywhile (my @results = $sth->fetchrow_array) { 可以正常工作,因为现在每次循环时,@results 都是一个不同的数组。

【讨论】:

  • 谢谢...我遵循这个推理。我对这个循环行为的假设是 @results 的元素被加载了单个结果行的字段,并在每次迭代时将自身重置为下一行的字段
  • @Cheese:这是正确的,但数组引用(您正在存储的实际内容)在每次迭代时都不会更改。所以你只是用下一个结果覆盖最后一行的结果。
  • @ether - 我现在明白了,谢谢。关于这个变量使用/操作的特定领域(对于数组或其他)我应该知道的还有其他秘密吗?您知道任何好的参考/指南吗?我一边自学 Perl,一边被这些错综复杂的东西困住
  • @Cheese: [perldoc perldata](http:/perldoc.perl.org/perldata.html), [perldoc perldsc](http:/perldoc.perl.org/perldsc.html), [ perldoc perlreftut](http://perldoc.perl.org/perlreftut.html)。还有Beginning PerlIntermediate PerlMastering Perl等书籍。
【解决方案3】:

为什么要循环?这样做更容易:

my $results = $sth->fetchall_arrayref();

或者如果你坚持使用数组变量:

my @results = @{$sth->fetchall_arrayref()};

【讨论】:

  • " 无法通过包 "sth" 定位对象方法 "fetchall_arrayref" (也许你忘记加载 "sth"?) "
  • 那是因为他犯了一个小错误,在$sth 上省略了$ 印记。我修好了。
  • 糟糕,抱歉...感谢您的修复。
猜你喜欢
  • 2011-12-03
  • 1970-01-01
  • 1970-01-01
  • 2020-06-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-28
相关资源
最近更新 更多