在PERL中使用push时清空循环内的数组



我正在编写一个子程序,该子程序从另一个数组打印非冗余元素的数组。

这段代码在我的子程序中。

foreach (@old_table) { push(@new_table, $_) unless ($seen{$_}++); }
print "@new_table" . "n";                           

然后,我在主程序中的循环中调用我的子例程,对于第一次迭代,它是可以的,并且我的新表包含一个旧表的出现。但在那之后,@new_table保留了来自过去迭代的元素,并且打印结果为假。

我尝试清空子程序中的@new_table,如

@new_table = ();
foreach (@old_table) { push(@new_table, $_) unless ($seen{$_}++); }
print "@new_table" . "n";       

但是,除第一次迭代外,我的@new_table在所有迭代中都变为空。

这个有什么问题?我该怎么解决?

由于作用域不正确,您正在重用以前过程的@new_table%seen。在循环之前创建这些。

my @new_table;
my %seen;
foreach (@old_table) { push(@new_table, $_) unless ($seen{$_}++); }
print "@new_table" . "n";

这可以简化为

my %seen;
my @new_table = grep { !$seen{$_}++ } @old_table;
print "@new_tablen";

你也可以使用

use List::MoreUtils qw( uniq );
my @new_table = uniq(@old_table);
print "@new_tablen";

您正在使用use strict; use warnings;,对吗?如果不是,你应该是。永远。

您可以从List::MoreUtils中尝试uniq来删除冗余元素。

my @new_table = uniq(@old_table);

引用perldoc

uniq列表
不同列表

通过剥离list中的重复值返回新列表。返回列表中元素的顺序与list中的相同。在里面标量上下文,返回LIST中唯一元素的数目。

           my @x = uniq 1, 1, 2, 2, 3, 5, 3, 4; # returns 1 2 3 5 4
           my $x = uniq 1, 1, 2, 2, 3, 5, 3, 4; # returns 5

最新更新