如何从Perl中的数组中删除重复的项目?

我在Perl中有一个数组:

my @my_array = ("one","two","three","two","three"); 

如何从数组中删除重复项?

您可以按照perlfaq4中的说明来做这样的事情:

 sub uniq { my %seen; grep !$seen{$_}++, @_; } my @array = qw(one two three two three); my @filtered = uniq(@array); print "@filtered\n"; 

输出:

 one two three 

如果您想使用模块,请尝试List::MoreUtilsuniq函数

Perl文档带有一个很好的FAQ集合。 你的问题经常被问到:

 % perldoc -q duplicate 

从上面的命令的输出复制并粘贴的答案如下所示:

 在/usr/local/lib/perl5/5.10.0/pods/perlfaq4.pod中find
 我怎样才能从列表或数组中删除重复的元素?
    (由布莱恩福伊提供)

   使用散列。 当你认为“独特”或“重复”的话,想想
    “散列键”。

   如果你不关心元素的顺序,你可以
   创build散列,然后提取密钥。 你怎么样并不重要
   创build哈希:只是你使用“键”来获得独特的元素。

       我的%哈希=地图{$ _,1} @array;
        #或者哈希片:@hash {@array} =();
        #或者一个foreach:$ hash {$ _} = 1 foreach(@array);

       我的@unique = keys%hash;

   如果您想使用模块,请尝试使用“uniq”function
    “名单:: MoreUtils”。 在列表上下文中它返回唯一的元素,
   保留他们的名单。 在标量的情况下,它返回
   独特元素的数量。

       使用List :: MoreUtils qw(uniq);

       我的@unique = uniq(1,2,3,4,4,5,6,5,7);  #1,2,3,4,5,6,7
       我的$ unique = uniq(1,2,3,4,4,5,6,5,7);  #7

   你也可以浏览每个元素,跳过你看过的元素
   之前。 使用散列来跟踪。 第一次循环看到一个
   元素,该元素没有在%被查看的键。  “下一个”语句创build
   键,并立即使用它的值,这是“undef”,所以循环
   继续“推”,并增加该键的价值。 下一个
   当循环看到相同的元素时,其密钥存在于散列中
   该键的值是真的(因为它不是0或“undef”),所以
   接下来跳过这个迭代,循环进入下一个元素。

       我的@unique =();
       我看到%=();

        foreach我的$ elem(@array)
        {
         接下来如果$看到{$ elem} ++;
         推@unique,$ elem;
        }

   你可以使用grep来更简单地写出这个,它也是一样的
   事情。

       我看到%=();
       我的@unique = grep {!  $ seen {$ _} ++} @array;

从CPAN安装List :: MoreUtils

然后在你的代码中:

 use strict; use warnings; use List::MoreUtils qw(uniq); my @dup_list = qw(1 1 1 2 3 4 4); my @uniq_list = uniq(@dup_list); 

我通常的做法是:

 my %unique = (); foreach my $item (@myarray) { $unique{$item} ++; } my @myuniquearray = keys %unique; 

如果您使用散列并将项目添加到散列。 你也有奖励知道每个项目出现在列表中的次数。

variables@array是具有重复元素的列表

 %seen=(); @unique = grep { ! $seen{$_} ++ } @array; 

可以用一个简单的Perl一个class轮来完成。

 my @in=qw(1 3 4 6 2 4 3 2 6 3 2 3 4 4 3 2 5 5 32 3); #Sample data my @out=keys %{{ map{$_=>1}@in}}; # Perform PFM print join ' ', sort{$a<=>$b} @out;# Print data back out sorted and in order. 

PFM块做到这一点:

@in中的数据被input到MAP中。 MAPbuild立一个匿名散列。 密钥从散列中提取并送入@out

最后一个是相当不错的。 我只是稍微调整一下:

 my @arr; my @uniqarr; foreach my $var ( @arr ){ if ( ! grep( /$var/, @uniqarr ) ){ push( @uniqarr, $var ); } } 

我认为这可能是最可读的方式。

试试这个,似乎uniq函数需要一个sorting列表才能正常工作。

 use strict; # Helper function to remove duplicates in a list. sub uniq { my %seen; grep !$seen{$_}++, @_; } my @teststrings = ("one", "two", "three", "one"); my @filtered = uniq @teststrings; print "uniq: @filtered\n"; my @sorted = sort @teststrings; print "sort: @sorted\n"; my @sortedfiltered = uniq sort @teststrings; print "uniq sort : @sortedfiltered\n"; 

使用唯一散列键的概念:

 my @array = ("a","b","c","b","a","d","c","a","d"); my %hash = map { $_ => 1 } @array; my @unique = keys %hash; print "@unique","\n"; 

输出:acbd

方法1:使用散列

逻辑:哈希可以只有唯一的键,所以迭代数组,将任何值分配给数组的每个元素,保持元素作为该哈希的关键。 返回散列键,它是你唯一的数组。

 my @unique = keys {map {$_ => 1} @array}; 

方法2:扩展方法1的可重用性

如果我们要在代码中多次使用这个function,最好做一个子程序。

 sub get_unique { my %seen; grep !$seen{$_}++, @_; } my @unique = get_unique(@array); 

方法3:使用模块List::MoreUtils

 use List::MoreUtils qw(uniq); my @unique = uniq(@array);