如何从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::MoreUtils
的uniq
函数
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);