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

时间:2023-01-21 15:38:07

I have an array in Perl:

我有一个Perl数组:

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

How do I remove the duplicates from the array?

如何从数组中删除副本?

10 个解决方案

#1


147  

You can do something like this as demonstrated in perlfaq4:

你可以像perlfaq4所展示的那样做:

sub uniq {
    my %seen;
    grep !$seen{$_}++, @_;
}

my @array = qw(one two three two three);
my @filtered = uniq(@array);

print "@filtered\n";

Outputs:

输出:

one two three

If you want to use a module, try the uniq function from List::MoreUtils

如果您想使用模块,请尝试列表::MoreUtils中的uniq函数

#2


117  

The Perl documentation comes with a nice collection of FAQs. Your question is frequently asked:

Perl文档附带了一系列常见问题。你的问题经常被问到:

% perldoc -q duplicate

The answer, copy and pasted from the output of the command above, appears below:

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

Found in /usr/local/lib/perl5/5.10.0/pods/perlfaq4.pod
 How can I remove duplicate elements from a list or array?
   (contributed by brian d foy)

   Use a hash. When you think the words "unique" or "duplicated", think
   "hash keys".

   If you don't care about the order of the elements, you could just
   create the hash then extract the keys. It's not important how you
   create that hash: just that you use "keys" to get the unique elements.

       my %hash   = map { $_, 1 } @array;
       # or a hash slice: @hash{ @array } = ();
       # or a foreach: $hash{$_} = 1 foreach ( @array );

       my @unique = keys %hash;

   If you want to use a module, try the "uniq" function from
   "List::MoreUtils". In list context it returns the unique elements,
   preserving their order in the list. In scalar context, it returns the
   number of unique elements.

       use List::MoreUtils qw(uniq);

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

   You can also go through each element and skip the ones you've seen
   before. Use a hash to keep track. The first time the loop sees an
   element, that element has no key in %Seen. The "next" statement creates
   the key and immediately uses its value, which is "undef", so the loop
   continues to the "push" and increments the value for that key. The next
   time the loop sees that same element, its key exists in the hash and
   the value for that key is true (since it's not 0 or "undef"), so the
   next skips that iteration and the loop goes to the next element.

       my @unique = ();
       my %seen   = ();

       foreach my $elem ( @array )
       {
         next if $seen{ $elem }++;
         push @unique, $elem;
       }

   You can write this more briefly using a grep, which does the same
   thing.

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

#3


65  

Install List::MoreUtils from CPAN

从CPAN安装列表:MoreUtils

Then in your code:

然后在你的代码:

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);

#4


22  

My usual way of doing this is:

我通常的做法是:

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

If you use a hash and add the items to the hash. You also have the bonus of knowing how many times each item appears in the list.

如果使用散列并将项添加到散列中。您还可以知道每个项目出现在列表中的次数。

#5


7  

Can be done with a simple Perl one liner.

可以用一个简单的Perl一行程序完成。

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.

The PFM block does this:

PFM块的作用是:

Data in @in is fed into MAP. MAP builds an anonymous hash. Keys are extracted from the hash and feed into @out

@in中的数据被输入到MAP中。MAP构建一个匿名散列。键从散列中提取出来,然后输入@out

#6


6  

The variable @array is the list with duplicate elements

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

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

#7


3  

That last one was pretty good. I'd just tweak it a bit:

最后一个很好。我稍微调整一下:

my @arr;
my @uniqarr;

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

I think this is probably the most readable way to do it.

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

#8


3  

Method 1: Use a hash

Logic: A hash can have only unique keys, so iterate over array, assign any value to each element of array, keeping element as key of that hash. Return keys of the hash, its your unique array.

逻辑:哈希只能有唯一的键,所以遍历数组,为数组的每个元素分配任何值,将元素作为哈希的键。返回散列的键,它是唯一的数组。

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

Method 2: Extension of method 1 for reusability

Better to make a subroutine if we are supposed to use this functionality multiple times in our code.

如果我们要在代码中多次使用这个功能,那么最好做一个子例程。

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

Method 3: Use module List::MoreUtils

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

#9


1  

Using concept of unique hash keys :

使用唯一的散列键的概念:

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

Output: a c b d

输出:a c b d。

#10


0  

Try this, seems the uniq function needs a sorted list to work properly.

尝试一下,似乎uniq函数需要一个排序的列表才能正常工作。

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";

#1


147  

You can do something like this as demonstrated in perlfaq4:

你可以像perlfaq4所展示的那样做:

sub uniq {
    my %seen;
    grep !$seen{$_}++, @_;
}

my @array = qw(one two three two three);
my @filtered = uniq(@array);

print "@filtered\n";

Outputs:

输出:

one two three

If you want to use a module, try the uniq function from List::MoreUtils

如果您想使用模块,请尝试列表::MoreUtils中的uniq函数

#2


117  

The Perl documentation comes with a nice collection of FAQs. Your question is frequently asked:

Perl文档附带了一系列常见问题。你的问题经常被问到:

% perldoc -q duplicate

The answer, copy and pasted from the output of the command above, appears below:

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

Found in /usr/local/lib/perl5/5.10.0/pods/perlfaq4.pod
 How can I remove duplicate elements from a list or array?
   (contributed by brian d foy)

   Use a hash. When you think the words "unique" or "duplicated", think
   "hash keys".

   If you don't care about the order of the elements, you could just
   create the hash then extract the keys. It's not important how you
   create that hash: just that you use "keys" to get the unique elements.

       my %hash   = map { $_, 1 } @array;
       # or a hash slice: @hash{ @array } = ();
       # or a foreach: $hash{$_} = 1 foreach ( @array );

       my @unique = keys %hash;

   If you want to use a module, try the "uniq" function from
   "List::MoreUtils". In list context it returns the unique elements,
   preserving their order in the list. In scalar context, it returns the
   number of unique elements.

       use List::MoreUtils qw(uniq);

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

   You can also go through each element and skip the ones you've seen
   before. Use a hash to keep track. The first time the loop sees an
   element, that element has no key in %Seen. The "next" statement creates
   the key and immediately uses its value, which is "undef", so the loop
   continues to the "push" and increments the value for that key. The next
   time the loop sees that same element, its key exists in the hash and
   the value for that key is true (since it's not 0 or "undef"), so the
   next skips that iteration and the loop goes to the next element.

       my @unique = ();
       my %seen   = ();

       foreach my $elem ( @array )
       {
         next if $seen{ $elem }++;
         push @unique, $elem;
       }

   You can write this more briefly using a grep, which does the same
   thing.

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

#3


65  

Install List::MoreUtils from CPAN

从CPAN安装列表:MoreUtils

Then in your code:

然后在你的代码:

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);

#4


22  

My usual way of doing this is:

我通常的做法是:

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

If you use a hash and add the items to the hash. You also have the bonus of knowing how many times each item appears in the list.

如果使用散列并将项添加到散列中。您还可以知道每个项目出现在列表中的次数。

#5


7  

Can be done with a simple Perl one liner.

可以用一个简单的Perl一行程序完成。

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.

The PFM block does this:

PFM块的作用是:

Data in @in is fed into MAP. MAP builds an anonymous hash. Keys are extracted from the hash and feed into @out

@in中的数据被输入到MAP中。MAP构建一个匿名散列。键从散列中提取出来,然后输入@out

#6


6  

The variable @array is the list with duplicate elements

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

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

#7


3  

That last one was pretty good. I'd just tweak it a bit:

最后一个很好。我稍微调整一下:

my @arr;
my @uniqarr;

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

I think this is probably the most readable way to do it.

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

#8


3  

Method 1: Use a hash

Logic: A hash can have only unique keys, so iterate over array, assign any value to each element of array, keeping element as key of that hash. Return keys of the hash, its your unique array.

逻辑:哈希只能有唯一的键,所以遍历数组,为数组的每个元素分配任何值,将元素作为哈希的键。返回散列的键,它是唯一的数组。

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

Method 2: Extension of method 1 for reusability

Better to make a subroutine if we are supposed to use this functionality multiple times in our code.

如果我们要在代码中多次使用这个功能,那么最好做一个子例程。

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

Method 3: Use module List::MoreUtils

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

#9


1  

Using concept of unique hash keys :

使用唯一的散列键的概念:

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

Output: a c b d

输出:a c b d。

#10


0  

Try this, seems the uniq function needs a sorted list to work properly.

尝试一下,似乎uniq函数需要一个排序的列表才能正常工作。

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";