[첫화면으로]Perl/Perlfaq4-40

마지막으로 [b]

1. 리스트나 배열에서 중복된 원소를 제거하는 법 (How can I remove duplicate elements from a list or array?)

해쉬를 사용한다. "고유한" 또는 "중복된" 것을 다룰때는 "해쉬 키"를 생각하라.

원소의 순서를 따지지 않는다면, 해쉬를 생성하고 키를 추출하면 된다. 해쉬를 어떻게 생성하는지는 중요하지 않다: keys를 사용하여 고유한 원소들을 얻어낼 수 있다.

        my %hash   = map { $_, 1 } @array;
        # 또는 해쉬 슬라이스를 사용:
        @hash{ @array } = ();
        # 또는 foreach를 사용:
        $hash{$_} = 1 foreach ( @array );

        my @unique = keys %hash;

모듈을 사용하고 싶다면, Cpan:List::MoreUtils 모듈의 uniq 함수를 사용해 보라. 리스트 컨텍스트에서는 고유한 원소들을 반환하며, 리스트 안에서의 순서도 유지된다. 스칼라 컨텍스트에서는 고유한 원소의 갯수를 반환한다.

        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

각 원소들을 훑으면서 이미 봤던 원소를 건너뛰는 수도 있다. 봤던 원소들을 알아보기 위해서 해쉬를 사용한다. 루프 안에서 어떤 원소를 처음 봤을때는 %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;

이름:  
Homepage:
내용:
 


컴퓨터분류 Perl /Perlfaq

마지막 편집일: 2012-2-11 12:25 am (변경사항 [d])
1133 hits | Permalink | 변경내역 보기 [h] | 페이지 소스 보기