문제

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

모듈을 사용하려면 다음을 시도하십시오. uniq 기능 List::MoreUtils

다른 팁

Perl 문서에는 유용한 FAQ 모음이 함께 제공됩니다.귀하의 질문은 자주 묻는 질문입니다:

% perldoc -q duplicate

위 명령의 출력에서 ​​복사하여 붙여넣은 대답은 다음과 같습니다.

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;

설치하다 목록::더보기Utils CPAN에서

그런 다음 코드에서:

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;

해시를 사용하고 항목을 해시에 추가하는 경우.또한 각 항목이 목록에 몇 번이나 나타나는지 알 수 있는 보너스도 있습니다.

간단한 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.

PFM 블록은 다음을 수행합니다.

@in의 데이터는 MAP에 입력됩니다.MAP은 익명 해시를 구축합니다.키는 해시에서 추출되어 @out에 공급됩니다.

@array 변수는 중복된 요소가 있는 목록입니다.

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

마지막 것은 꽤 좋았습니다.나는 그것을 조금 조정할 것입니다 :

my @arr;
my @uniqarr;

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

나는 이것이 아마도 가장 읽기 쉬운 방법이라고 생각합니다.

방법 1:해시를 사용하세요

논리:해시에는 고유 키만 있을 수 있으므로 배열을 반복하고 배열의 각 요소에 값을 할당하고 요소를 해당 해시의 키로 유지합니다.고유한 배열인 해시의 키를 반환합니다.

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

방법 2:재사용성을 위한 방법 1의 확장

코드에서 이 기능을 여러 번 사용해야 한다면 서브루틴을 만드는 것이 더 좋습니다.

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

방법 3:모듈 사용 List::MoreUtils

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

이전 답변은 이 작업을 수행하는 가능한 방법을 거의 요약합니다.

그러나 나는 수정을 제안합니다. ~하지 않다 걱정하다 계산 중복되지만 하다 순서에 신경쓰세요.

my @record = qw( yeah I mean uh right right uh yeah so well right I maybe );
my %record;
print grep !$record{$_} && ++$record{$_}, @record;

이전에 제안한 내용을 참고하세요. grep !$seen{$_}++ ... 증분 $seen{$_} 부정하기 전에 이미 발생했는지 여부에 관계없이 증가가 발생합니다. %seen 아니면.그러나 위의 내용은 다음과 같은 경우 단락됩니다. $record{$_} 한 번 들었던 내용을 떠나서 사실입니다. %record'.

자동 활성화와 해시 키의 존재를 활용하는 말도 안되는 일을 할 수도 있습니다.

...
grep !(exists $record{$_} || undef $record{$_}), @record;

그러나 이로 인해 약간의 혼란이 발생할 수 있습니다.

그리고 주문이나 중복 횟수에 관심이 없다면 해시 슬라이스와 방금 언급한 트릭을 사용하여 또 다른 해킹을 할 수 있습니다.

...
undef @record{@record};
keys %record; # your record, now probably scrambled but at least deduped

이것을 시도해 보세요. 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";

고유한 해시 키 개념 사용:

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

산출:에이씨비디

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top