Perl Sort 함수 용법 총화 및 사용 사례

9449 단어 Perl
1)sort 함수 사용법
sort LISTsort BLOCK LISTsort SUBNAME LIST
sort 의 용법 은 위의 세 가지 형식 과 같다.LIST 를 정렬 하고 정렬 된 목록 을 되 돌려 줍 니 다.SUBNAME 나 BLOCK 를 무시 하면 sort 는 표준 문자열 비교 순서 로 진행 합 니 다(예 를 들 어 ASCII 순서).SUBNAME 를 지정 하면 실제 하위 함수 의 이름 입 니 다.이 하위 함 수 는 2 개의 목록 요 소 를 비교 하고'같 거나 0 이상 의 정수'를 되 돌려 줍 니 다.이것 은 요소 가 어떤 순서 로 sort(오름차,항등, 또는 내림차 순)에 의존 합 니 다.SUBNAME 대신 BLOCK 를 익명 의 서브 함수 로 제공 할 수도 있 습 니 다.효 과 는 같 습 니 다.
비교 되 는 두 개의 요 소 는 변수$a 와$b 에 임시 대 입 됩 니 다.인용 으로 전달 되 므 로$a 나$b 를 수정 하지 마 십시오.만약 하위 함 수 를 사용한다 면,그것 은 귀속 함수 가 될 수 없다.
2)용법 실례
1.숫자 순서 sort    

@array = (8, 2, 32, 1, 4, 16);
print join(' ', sort {$a <=> $b} @array), "
";
인쇄 결 과 는:   
1 2 4 8 16 32
이와 같은 것 은:
sub numerically { $a <=> $b };
print join(' ', sort numerically @array), "
";
이것 은 쉽게 이해 할 수 있 습 니 다.그것 은 자연수 순서에 따라 sort 를 진행 할 뿐 가끔 은 자세히 말 하지 않 습 니 다.
2.1 ASCII 순서(비 사전 순서)로 sort

@languages = qw(fortran lisp c c++ Perl python java);
print join(' ', sort @languages), "
";
인쇄 결과:
Perl c c++ fortran java lisp python
이것 은 다음 과 같다.
print join(' ', sort { $a cmp $b } @languages), "
";
ASCII 순 으로 순 위 를 매 기 는 것 도 별 말씀 을 요.
주의 하 세 요.숫자 를 ASCII 순서대로 sort 하면 결 과 는 당신 이 생각 하 는 것 과 다 를 수 있 습 니 다.

print join(' ', sort 1 .. 11), "
";
1 10 11 2 3 4 5 6 7 8 9
2.2 사전 순서 sort

use locale;
@array = qw(ASCII ascap at_large atlarge A ARP arp);
@sorted = sort { ($da = lc $a) =~ s/[/W_]+//g;
          ($db = lc $b) =~ s/[/W_]+//g;
          $da cmp $db;
          } @array;
print "@sorted
";
인쇄 결 과 는:  
A ARP arp ascap ASCII atlarge at_large
use locale 은 선택 할 수 있 습 니 다.code 의 호환성 을 향상 시 킵 니 다.만약 원본 데이터 가 국제 문 자 를 포함한다 면.use locale 은 cmp,lt,le,ge,lt 및 기타 일부 함수 의 조작 속성 에 영향 을 주 었 습 니 다.
atlarge 와 atlarge 순 서 는 출력 할 때 뒤 바 뀌 었 습 니 다.sort 순 서 는 같 지만(sort 중간 하위 함수 가 at 를 지 웠 습 니 다.큰 가운데 밑줄.이 점 이 발생 하 는 것 은 이 예시 가 perl 5.005 에서 실행 되 기 때문이다02 위.perl 버 전 5.6 전에 sort 함 수 는 같은 values 가 있 는 keys 의 우선 순 서 를 보호 하지 않 습 니 다.perl 버 전 5.6 과 더 높 은 버 전 은 이 순 서 를 보호 합 니 다.
주의 하 세 요.map,grep 든 sort 든 이 임시 변 수 를 보호 하 세 요$(sort 에 서 는$a 와$b)의 값 입 니 다.이 code 에서 변경 하지 마 십시오.$a 또는$b 를 교체 하 는 작업 s/[/W]+/g 전에$da 와$db 에 값 을 다시 부여 하면 원본 요 소 를 수정 하지 않 습 니 다.
3.내림차 sort 내림차 sort 가 간단 합 니 다.cmp 또는<=>전후의 조작 수 를 위 치 를 바 꾸 면 됩 니 다.
sort { $b <=> $a } @array;
또는 중간 블록 이나 하위 함수 의 반환 값 을 바 꾸 는 태그:
sort { -($a <=> $b) } @array;
또는 reverse 함 수 를 사용 합 니 다(이것 은 약간 비효 율 적 이지 만 읽 기 쉬 울 수도 있 습 니 다):
reverse sort { $a <=> $b } @array;
4.여러 keys 를 사용 하여 sort 를 진행 하려 면 여러 keys 로 sort 를 하고,or 로 연 결 된 모든 비교 작업 을 하나의 함수 에 넣 으 면 됩 니 다.주요 비교 조작 을 앞 에 두 고 부차적인 것 은 뒤에 두 세 요.

# An array of references to anonymous hashes
@employees = (
  { FIRST => 'Bill',   LAST => 'Gates',
    SALARY => 600000, AGE => 45 },
  { FIRST => 'George', LAST => 'Tester'
    SALARY => 55000, AGE => 29 },
  { FIRST => 'Steve', LAST => 'Ballmer',
    SALARY => 600000, AGE => 41 }
  { FIRST => 'Sally', LAST => 'Developer',
    SALARY => 55000, AGE => 29 },
  { FIRST => 'Joe',   LAST => 'Tester',
    SALARY => 55000, AGE => 29 },
);
sub seniority {
  $b->{SALARY}   <=> $a->{SALARY}
  or $b->{AGE}   <=> $a->{AGE}
  or $a->{LAST}   cmp $b->{LAST}
  or $a->{FIRST}   cmp $b->{FIRST}
}
@ranked = sort seniority @employees;
foreach $emp (@ranked) {
  print "$emp->{SALARY}/t$emp->{AGE}/t$emp->{FIRST}
    $emp->{LAST}
";
}
인쇄 결 과 는:
600000 45     Bill Gates
600000 41     Steve Ballmer
55000   29     Sally Developer
55000   29     George Tester
55000   29     Joe Tester
위 코드 는 복잡 해 보이 지만 실제로는 이해 하기 쉽 습 니 다.@employes 배열 의 요 소 는 익명 hash 입 니 다.익명 hash 는 실제 참조 입 니 다.->연산 자 를 사용 하여 값 에 접근 할 수 있 습 니 다.예 를 들 어$employees[0]->{SALARY}은 첫 번 째 익명 hash 에서 SALARY 에 대응 하 는 값 에 접근 할 수 있 습 니 다.그래서 상기 각 항목 을 비교 하면 잘 알 수 있 습 니 다.먼저 SALARY 의 값 을 비교 한 다음 에 AGE 의 값 을 비교 한 다음 에 LAST 의 값 을 비교 한 다음 에 FIRST 의 값 을 비교 합 니 다.앞의 두 가지 비 교 는 내림차 순 이 고,뒤의 두 가 지 는 오름차 순 이 니 헷 갈 리 지 마 세 요.
5.sort 새 배열

@x = qw(matt elroy jane sally);
@rank[sort { $x[$a] cmp $x[$b] } 0 .. $#x] = 0 .. $#x;
print "@rank
";
인쇄 결 과 는:   
2 0 1 3
여기 좀 헷 갈 리 지 않 아 요?자세히 보면 알 수 있다.0..$\#x 는 목록 입 니 다.값 은@x 배열 의 아래 표 시 됩 니 다.여기 가 0,1,2,3 입 니 다.$x[$a]cmp$x[$b]는@x 의 각 요 소 를 ASCII 순서대로 비교 하 는 것 입 니 다.그래서 sort 의 결 과 는@x 의 아래 표 시 를 정렬 하 는 목록 으로 되 돌아 갑 니 다.정렬 의 기준 은 이 아래 표 시 된@x 요소 의 ASCII 순서 입 니 다.sort 가 뭘 되 돌려 주 는 지 모 르 겠 어 요?@x 리 요소 의 ASCII 순 서 를 출력 합 니 다:

@x = qw(matt elroy jane sally);
print join ' ',sort { $a cmp $b } @x;
인쇄 결 과 는: 
elroy jane matt sally
이들 은@x 에 대응 하 는 아래 표 시 는 1,2,0,3 이 므 로 위 sort 에서 돌아 온 결 과 는 1,2,0,3 목록 입 니 다.@rank[1,2,0,3]=0..$\#x 는 간단 한 배열 할당 작업 이기 때문에@rank 의 결 과 는(2,0,1,3)입 니 다.
6.keys 를 눌 러 hash 를 sort

%hash = (Donald => Knuth, Alan => Turing, John => Neumann);
@sorted = map { { ($_ => $hash{$_}) } } sort keys %hash;
foreach $hashref (@sorted) {
  ($key, $value) = each %$hashref;
  print "$key => $value
";
}
인쇄 결 과 는:
Alan => Turing
Donald => Knuth
John => Neumann
위 코드 는 어렵 지 않 습 니 다.sort keys%hash%hash 의 keys ASCII 순서 로 목록 을 되 돌려 주 고 map 로 계산 합 니 다.map 에 이중{{}에 있 는{}은 익명 hash 입 니 다.즉,map 의 결 과 는 익명 hash 목록 입 니 다.아 시 겠 습 니까?그래서@sorted 배열 의 요 소 는 각각 익명 hash 입 니 다.%$hashref 를 통 해 반 인용 하면 키/value 값 에 접근 할 수 있 습 니 다.
7.values 에 따라 hash 를 sort

%hash = ( Elliot => Babbage,
      Charles => Babbage,
      Grace => Hopper,
      Herman => Hollerith
    );
@sorted = map { { ($_ => $hash{$_}) } }
        sort { $hash{$a} cmp $hash{$b}
              or $a cmp $b
            } keys %hash;
foreach $hashref (@sorted) {
  ($key, $value) = each %$hashref;
  print "$key => $value
";
}
인쇄 결 과 는:
Charles => Babbage
Elliot => Babbage
Herman => Hollerith
Grace => Hopper
hash keys 와 달리 hash values 의 유일 성 을 보장 할 수 없습니다.values 에 따라 sort hash 만 한다 면 다른 values 를 추가 하거나 삭제 할 때 같은 value 를 가 진 두 요소 의 sort 순서 가 바 뀔 수 있 습 니 다.안정 적 인 결 과 를 얻 기 위해 서 는 value 에 대해 주 sort 를 하고 key 에 대해 sort 를 해 야 합 니 다.
여기{$hash{$a}cmp$hash{$b}or$a cmp$b}은 value 를 누 르 고 key 를 두 번 누 르 면 sort 를 진행 합 니 다.sort 가 돌아 온 결 과 는 정렬 된 keys 목록 입 니 다.그리고 이 목록 은 map 에 넘 겨 계산 하여 익명 hash 목록 을 되 돌려 줍 니 다.방문 방법 이 앞의 것 과 같 아서 우연히 상세 하 게 서술 하지 못 했다.
8.파일 에 있 는 단 어 를 sort 하고 중복 되 는 것 을 제거 합 니 다

perl -0777ane '$, = "
"; @uniq{@F} = (); print sort keys %uniq' file
여러분,이런 용법 을 사용 해 보 세 요.저도 잘 모 르 겠 습 니 다.@uniq{@F}=()는 hash slice 를 사용 하여 hash 를 만 들 었 습 니 다.keys 는 파일 의 유일한 단어 입 니 다.이 용법 은 의미 상$uniq{$F[0],$F[1],...$F[$\#F]}=()
각 옵션 설명 은 다음 과 같 습 니 다.
-0777   -         ,     
-a     -   , @F
-e     -  
-n     -   :while (<>) { ... }
$,     -   print
file   -  
9.효율 적 인 sorting:Orchish 알고리즘 과 Schwartzian 변환 은 모든 key,sort 의 하위 함수 에 여러 번 호출 됩 니 다.sort 실행 시간 에 매우 신경 을 쓴다 면,키 마다 다음 예제 만 계산 할 수 있 도록 Orchish 알고리즘 이나 Schwartzian 변환 을 사용 할 수 있 습 니 다.파일 수정 날짜 에 따라 sort 파일 목록 을 사용 할 수 있 습 니 다.
#     --            
@sorted = sort { -M $a <=> -M $b } @filenames;

# Orcish -- hash keys
@sorted = sort { ($modtimes{$a} ||= -M $a) <=>
          ($modtimes{$b} ||= -M $b)
          } @filenames;

교묘 한 알고리즘,그 렇 죠?파일 의 수정 날 짜 는 스 크 립 트 가 실행 되 는 동안 기본적으로 변 하지 않 기 때문에-M 연산 을 한 번 하고 저장 하면 되 잖 아 요.다음은 Schwartzian 변환 의 용법 입 니 다.
@sorted = map( { $_->[0] }
          sort( { $a->[1] <=> $b->[1] }
              map({ [$_, -M] } @filenames)
            )
        );
이 code 는 map,sort 를 결합 하여 여러 층 으로 나 누 었 습 니 다.예전 에 제 시 했 던 방법 을 기억 하고 뒤에서 앞 을 봅 니 다.map({ [$_, -M]}@filenames)목록 을 되 돌려 줍 니 다.목록 요 소 는 익명 배열 입 니 다.익명 배열 의 첫 번 째 값 은 파일 이름 이 고 두 번 째 값 은 파일 의 수정 날짜 입 니 다.
sort({$a->[1]<=>$b->[1]}...위 에서 발생 한 익명 배열 목록 을 sort 합 니 다.파일 의 수정 날짜 에 따라 sortsort 를 되 돌려 주 는 결 과 는 정렬 된 익명 배열 입 니 다.
가장 바깥쪽 맵({$->[0.}..간단 합 니 다.위 sort 에서 생 성 된 익명 배열 에서 파일 이름 을 추출 합 니 다.이 파일 이름 은 수 정 된 날짜 에 따라 sort 를 진행 한 것 이 고 파일 마다-M 만 실 행 했 습 니 다.이것 이 바로 유명한 Schwartzian 전환 입 니 다.이런 용법 은 외국 perl 사용자 들 사이 에서 매우 유행 합 니 다.

좋은 웹페이지 즐겨찾기