답변:
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
my
이 범위에서 어휘, 그것의 좋은 그렇게. 즉, 더 설명적인 변수 이름을 선택할 수 있습니다.
$::a
와 $::b
, 그것을하지 않을까요?
sub uniq { my %seen; grep !$seen{$_}++, @_ }
무료로 주문을 유지하기 때문에 더 나은 구현입니다. 또는 List :: MoreUtils에서 하나를 사용하십시오.
Perl 문서에는 멋진 FAQ 모음이 포함되어 있습니다. 자주 묻는 질문 :
% perldoc -q duplicate
위 명령의 출력에서 복사하여 붙여 넣은 답변은 다음과 같습니다.
/usr/local/lib/perl5/5.10.0/pods/perlfaq4.pod에 있습니다. 목록이나 배열에서 중복 요소를 제거하려면 어떻게해야합니까? (brian d foy 제공) 해시를 사용하십시오. "고유 한"또는 "중복 된"이라는 단어를 생각할 때 "해시 키". 요소의 순서에 신경 쓰지 않으면 그냥 할 수 있습니다. 해시를 만든 다음 키를 추출하십시오. 당신이 어떻게 중요하지 않습니다 해시 만들기 : "키"를 사용하여 고유 한 요소를 가져 오면됩니다. 내 % hash = map {$ _, 1} @array; # 또는 해시 슬라이스 : @hash {@array} = (); # 또는 foreach : $ hash {$ _} = 1 foreach (@array); 내 @unique = 키 % hash; 모듈을 사용하려면 "uniq"기능을 사용해보십시오. "List :: MoreUtils". 목록 컨텍스트에서 고유 한 요소를 반환합니다. 목록에서 순서를 유지합니다. 스칼라 컨텍스트에서 고유 한 요소 수 List :: MoreUtils 사용 qw (uniq); 내 @ 고유 = 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 또한 각 요소를 살펴보고 본 요소를 건너 뛸 수 있습니다 전에. 해시를 사용하여 추적하십시오. 루프가 처음으로 % Seen에는 해당 요소가 없습니다. "다음"문은 키는 즉시 "undef"라는 값을 사용하므로 루프 "푸시"로 계속 진행하여 해당 키의 값을 증가시킵니다. 다음 루프가 동일한 요소를 볼 때 그 키는 해시에 존재합니다. 해당 키의 값은 0이거나 "unef"가 아니기 때문에 true이므로 next는 해당 반복을 건너 뛰고 루프는 다음 요소로 이동합니다. 내 @ 고유 = (); 내 % seen = (); 내 $ elem을 @each (@array) { 다음에 $ seen {$ elem} ++; @unique, $ elem을 밀어; } grep을 사용하여 더 짧게 작성할 수 있습니다. 알맞은 것. 내 % seen = (); 내 @ 고유 = grep {! $ seen {$ _} ++} @array;
CPAN의 설치 목록 :: 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);
@dup_list
내부에 있어야 함uniq
@dups
이 작업을 수행하는 일반적인 방법은 다음과 같습니다.
my %unique = ();
foreach my $item (@myarray)
{
$unique{$item} ++;
}
my @myuniquearray = keys %unique;
해시를 사용하고 항목을 해시에 추가하는 경우. 또한 각 항목이 목록에 나타나는 횟수를 아는 보너스도 있습니다.
간단한 펄 원 라이너로 할 수 있습니다.
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으로 피드
논리 : 해시는 고유 키 만 가질 수 있으므로 배열을 반복하고 배열의 각 요소에 값을 할당하고 요소를 해당 해시의 키로 유지하십시오. 고유 한 배열 인 해시의 키를 반환합니다.
my @unique = keys {map {$_ => 1} @array};
코드에서이 기능을 여러 번 사용해야한다면 서브 루틴을 만드는 것이 좋습니다.
sub get_unique {
my %seen;
grep !$seen{$_}++, @_;
}
my @unique = get_unique(@array);
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
sub uniq{ my %seen; undef @seen{@_}; keys %seen; }
깔끔한.
이것을보십시오, 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";
출력 : acbd