2010-06-29 4 views
9

을 해시하는 배열 참조 정렬 : 펄에 다음 줄을 실행 한 후에

my $data = `curl '$url'`; 
my $pets = XMLin($data)->(pets); 

내가 해시에 대한 참조가 포함 된 배열 참조가 : 펄에서

$VAR1 = [ 
     { 
     'title' => 'cat', 
     'count' => '210' 
     }, 
     { 
     'title' => 'dog', 
     'count' => '210' 
     } 
] 

을, 나는 해시를 정렬 할 처음에는 개수로, 그리고 부차적으로는 제목으로. 그런 다음 STDOUT에 각 줄 바꿈에 대한 제목이 인쇄되도록 인쇄하십시오.

답변

9

당신이 오름차순 내림차순 수와 제목을 원하는 가정 : 소형 코드는 기능적인 스타일로 작성

print map join(" ", @$_{qw/ count title /}) . "\n", 
     sort { $b->{count} <=> $a->{count} 
         || 
      $a->{title} cmp $b->{title} } 
     @$pets; 

. 그것을 이해하는 데 도움이되도록,보다 익숙하고 필수적인 스타일의 동급 코드를 살펴 보겠습니다.

펄의 sort 연산자는 비교를 제외하고 옵션의 기능을 설명하는 이름을 지정할 수있는 선택적 SUBNAME 매개 변수를 사용합니다. 이 작업을 수행 할 때 하위 이름을 by_으로 시작하여 sort by_...을 자연스럽게 준비하는 것이 좋습니다.

은 더 쉼표이 양식의 SUBNAME를 다음 없다는 것을

sub by_count_then_title { 
    $b->{count} <=> $a->{count} 
       || 
    $a->{title} cmp $b->{title} 
} 

my @sorted = sort by_count_then_title @$pets; 

노트를 작성했을 수도, 시작합니다!

또 다른 주석 작성자의 질문에 대답하려면 ||이 아닌 orby_count_then_title에 사용하면 더 쉽게 읽을 수 있습니다. <=>cmphave higher precedence (더 밀접하게 바인딩하는 것으로 생각할 수 있음)은 ||or보다 엄격하므로 스타일이 중요합니다. 좀 더 익숙한 선택

foreach my $p (@sorted) { 
    print "$p->{count} $p->{title}\n"; 
} 

펄 수 있습니다

는 각 값을 가져옵니다 변수를 지정하지 않은 경우 $_을 사용하여 정렬 된 배열을 인쇄하려면, 그래서 다음과 같은 의미가 있습니다

for

for (@sorted) { 
    print "$_->{count} $_->{title}\n"; 
} 
foreach 키워드는 동의어입니다,하지만 난 위의 사용, , foreach 내가 var에 이름을려고하면 찾을 iable 또는 for이면 자연스럽게 읽습니다.

map print("$_->{count} $_->{title}\n"), @sorted; 

당신은 또한 map을 통해 print을 촉진 수 : 대신 다르지 않다, map, foreach의 가까운 사촌을 사용하여

마지막으로

print map "$_->{count} $_->{title}\n", 
     @sorted; 

, $_->{...}의 반복을 피하기 위해 hash slice@$_{"count", "title"}은 루프의 현재 레코드에서 count 및 title과 관련된 값을 제공합니다.값을 갖는, 우리는 하나의 공간을 join하고 그 결과에 줄 바꿈을 추가 할 필요가있다, 그래서

print map join(" ", @$_{qw/ count title /}) . "\n", 
     @sorted; 

qw// 문자열의 목록을 작성하기위한 속기는 것을 기억하십시오. 이 예가 보여주는 것처럼 map 표현식을 앞뒤 (또는 들여 쓰는 방식)로 읽습니다. 먼저 레코드를 정렬 한 다음 서식을 지정한 다음 인쇄합니다.

당신은 이름을 비교 임시 @sorted을 제거하지만 호출 할 수 있습니다 join의 응용 프로그램이 후, 당신의 취향에 너무 자세한 경우

print map join(" ", @$_{qw/ count title /}) . "\n", 
     sort by_count_then_title 
     @$pets; 

을 의미하는 "지도"무엇

print map "@$_{qw/ count title /}\n", 
     sort by_count_then_title 
     @$pets; 
+0

/위의 코드에서 무엇을합니까? 왜 두 개의 다른 중괄호 집합에 두 속성을 지정할 필요가 없었습니까? – syker

+0

@syker :'map'은 정렬 된 배열의 각 해시를 가져 와서'count'와'title' 값을 공백으로 구분 된 한 줄에 출력합니다. @gbacon : sort by any-any 예제에서 항상'||'을 볼 때 당신의 정렬에서'|| '와'or'를 사용하는 것에 차이가 있는지 설명 할 가치가 있습니다. 어떤 상황에서도보다 가독성이 높은 '또는'이 다르게 동작 할 가능성이 있습니까? – Zaid

+0

@syker @Zaid 업데이트 된 답변보기. –

관련 문제