如何在Perl数组中打印唯一元素?

时间:2009-01-13 16:21:53

标签: perl arrays unique

我在while语句中将元素推送到数组中。每个元素都是教师的名字。当循环结束时,最终在数组中出现重复的教师名称。有时它们在阵列中并不是彼此相邻,有时它们是。

如何在完成获取值后才能打印该数组中的唯一值?每次我想要打印元素时都不需要解析整个数组。

在将所有内容推入数组后继承代码:

$faculty_len = @faculty;
$i=0;
while ($i != $faculty_len)
{
        printf $fh '"'.$faculty[$i].'"';
        $i++;
}   

10 个答案:

答案 0 :(得分:42)

use List::MoreUtils qw/ uniq /;
my @unique = uniq @faculty;
foreach ( @unique ) {
    print $_, "\n";
}

答案 1 :(得分:33)

您最好的选择是使用(基本上)内置工具,例如uniq(as described by innaM)

如果您无法使用uniq并希望保留顺序,则可以使用grep来模拟它。

my %seen;
my @unique = grep { ! $seen{$_}++ } @faculty;
# printing, etc.

首先给出一个散列,其中每个键都是每个条目。然后,迭代每个元素,计算它们中的元素数量,并添加第一个元素。 (更新了brian d foy的评论)

答案 2 :(得分:14)

我建议将其推入哈希。 像这样:

my %faculty_hash = ();
foreach my $facs (@faculty) {
  $faculty_hash{$facs} = 1;
}
my @faculty_unique = keys(%faculty_hash);

答案 3 :(得分:5)

@array1 = ("abc", "def", "abc", "def", "abc", "def", "abc", "def", "xyz");

@array1 = grep { ! $seen{ $_ }++ } @array1;

print "@array1\n"; 

答案 4 :(得分:5)

perldoc中的多个解决方案回答了这个问题。只需在命令行键入:

perldoc -q duplicate

答案 5 :(得分:4)

请注意:某些包含散列的答案会改变数组的顺序。哈希没有任何顺序,因此获取键或值将使列表具有未定义的顺序。

这不适用于grep { ! $seen{$_}++ } @faculty

答案 6 :(得分:3)

这是一个单行程序命令,用于按照它出现的顺序打印唯一的行。

perl -ne '$seen{$_}++ || print $_' fileWithDuplicateValues

答案 7 :(得分:2)

我刚刚找到了陈腐的3班轮,享受

my %uniq; 
undef @uniq(@non_uniq_array); 
my @uniq_array = keys %uniq; 

答案 8 :(得分:2)

只是另一种方法,只有在不关心订单时才有用

my %hash;
@hash{@faculty}=1;
my @unique=keys %hash;

如果您想避免声明一个新变量,可以使用某种方式未被记录的全局变量%_

@_{@faculty}=1;
my @unique=keys %_;

答案 9 :(得分:0)

如果您需要以任何方式处理教师列表,那么将数组上的映射转换为用于键合并然后排序键的哈希是另一种好方法:

my @deduped = sort keys %{{ map { /.*/? ($_,1):() } @faculty }};
print join("\n", @deduped)."\n";

您可以通过更改/.*/正则表达式来处理列表以进行相应的选择或解析和捕获,并且您可以通过使($_,1):()任意复杂来输出一个或多个变异的非唯一键。< / p>

如果您需要使用替换正则表达式修改正在进行中的数据,例如从名称中移除点(s/\.//g),则根据上述模式进行的替换将改变原始@faculty$_别名引起的数组。您可以通过制作$_数组的匿名副本来解决@faculty别名问题(请参阅所谓的"baby cart" operator):

my @deduped = sort keys %{{ map {/.*/? do{s/\.//g; ($_,1)}:()} @{[ @faculty ]} }};
print join("\n", @deduped)."\n";
print "Unmolested array:\n".join("\n", @faculty)."\n";

在更新版本的Perl中,您可以传递keys一个hashref,并且可以使用非破坏性替换:

my @deduped = sort keys { map { /.*/? (s/\.//gr,1):() } @faculty };

否则,其他地方的grep$seen[$_]++解决方案可能更合适。