1. 리스트나 배열에서 중복된 원소를 제거하는 법 (How can I remove duplicate elements from a list or array?)
해쉬를 사용한다. "고유한" 또는 "중복된" 것을 다룰때는 "해쉬 키"를 생각하라.
원소의 순서를 따지지 않는다면, 해쉬를 생성하고 키를 추출하면 된다. 해쉬를 어떻게 생성하는지는 중요하지 않다: keys
를 사용하여 고유한 원소들을 얻어낼 수 있다.
my %hash = map { $_, 1 } @array;
@hash{ @array } = ();
$hash{$_} = 1 foreach ( @array );
my @unique = keys %hash;
모듈을 사용하고 싶다면, List::MoreUtils 모듈의 uniq
함수를 사용해 보라. 리스트 컨텍스트에서는 고유한 원소들을 반환하며, 리스트 안에서의 순서도 유지된다. 스칼라 컨텍스트에서는 고유한 원소의 갯수를 반환한다.
use List::MoreUtils qw(uniq);
my @unique = uniq( 1, 2, 3, 4, 4, 5, 6, 5, 7 );
my $unique = uniq( 1, 2, 3, 4, 4, 5, 6, 5, 7 );
각 원소들을 훑으면서 이미 봤던 원소를 건너뛰는 수도 있다. 봤던 원소들을 알아보기 위해서 해쉬를 사용한다. 루프 안에서 어떤 원소를 처음 봤을때는 %seen
해쉬에 키가 없는 상태이다. next
문은 키를 생성하고 그 값을 곧바로 사용하는데, 이 때 그 값은 undef
이기 때문에 루프 안의 내용을 계속 진행하여 push
를 수행하고 그 키의 값을 증가시킨다. 루프가 똑같은 원소를 다음 번에 보게 될 경우 해쉬에 키가 존재하고 그 키의 값이 참이기 때문에 (0이나 undef
이 아니므로), 루프의 나머지 부분을 건너뛰고 다음 원소로 넘어간다.
my @unique = ();
my %seen = ();
foreach my $elem ( @array )
{
next if $seen{ $elem }++;
push @unique, $elem;
}
동일한 일을 하는 코드를 grep을 사용하여 더 간결하게 작성할 수 있다.
my %seen = ();
my @unique = grep { ! $seen{ $_ }++ } @array;
컴퓨터분류 Perl /Perlfaq