2011-04-08 5 views
6

perl 함수 map을 사용하여 다음 작업을 수행하는 방법을 찾고 있습니다. 해시가 주어 졌으므로 쌍 (키, 값)이며, 값은 지정된 매개 변수와 같거나 일치합니다.맵을 사용하여 지정된 값과 일치하는 (키, 값) 해시 세트를 추출합니다.

예를 들어, value = failed 인 경우 (키, 값) 쌍을 추출하고 싶지만 표현식 (즉, A 또는 REGEX로 시작하는 문자열) 일 수도 있습니다. 그래서 결과 값으로 값과 일치하는 키의 테이블뿐만 아니라 해시를 원합니다.

my %strings = (
    bla => "success", 
    ble => "failed", 
    bli => "failed", 
    foo => "success", 
    blo => "failed", 
    bar => "failed", 
    blu => "success" 
); 

my %failed_s =(); 

while (my ($k, $v) = each %strings) { 
    if ($v eq 'failed') {$failed_s{$k} = $v}; 
}; 

나는이 일을 몇 가지 방법을 시도했지만 좋은 결과가 그래서 나는 등,

my %failed_s = 
    map { { $_ => $strings{$_} } 
    if ($strings{$_}./failed/) } 
    keys %strings; 
my %failed_s = 
    map { ($strings{$_} eq 'failed') && 
      ($_, $strings{$_}) } 
    keys %strings; 

print "Dumper \%failed_s: \n" . Dumper(\%failed_s); 

을 참조, 허식, 결과에 대한 혼란스러워지고있어 생각없이 그것은 가능 여부되지 수 있습니다 이 경우지도를 사용하는 것이 효과적이지만 그 이유를 아는 데 도움이됩니다.

+0

펄의'grep'을 사용합니다. – knittl

+0

@knittl 시도해 보았습니다 만, 내가 그것을 보게되어 기쁘다는 예 또는 아이디어가 있다면 그것을 잘 작동시키는 법을 알 수 없었습니다! – Thomas

+1

@ mob의 [answer] (http://stackoverflow.com/questions/5597542/using-map-to-extract-hash-set-of-key-value-matching-specified-value/5597656#5597656)를 참조하십시오. –

답변

6

첫 번째 맵 예제에서는 원하는 요소가 아닌 단일 요소 해시 참조를 반환합니다.

두 번째 경우 && 연산자는 인수에 스칼라 컨텍스트를 적용하므로 목록 ($_, $strings{$_})은 목록의 마지막 항목 만 반환합니다.

은 당신이 찾고있는 무슨이다 :

my %failed_s = map { 
    $strings{$_} eq 'failed' ? ($_, $strings{$_}) :() 
} keys %strings; 
조건에 해당하는 경우 ? : 연산자 목록을 반환

하고, 빈리스트가 false 인 경우.

+0

빈 목록은지도가 $ _을 (를) 자신의 데이터를 전달하는 % 실패로 전달하지 못하게하는 것입니다. –

3

map FUNC, LIST은 LIST의 모든 요소에서 작동합니다. 함수는 일부 요소에 대해 빈 목록을 반환 할 수 있습니다 (Eric Strom의 답변에서 알 수 있듯이).

my %failed_s = map { 
    $_ => $strings{$_} 
} grep { $strings{$_} eq 'failed' } keys %strings; 
8

펄 몇 사람들이 키를 구별 할 수 있었다 정도로 논리를 해싱에 쉽게 접근을 즐기고있다 : map 만에 당신이 관심이 요소에서 작동하도록 또 다른 방법은 다른 필터를 사용하는 것입니다 가장 일반적인 구현 인 값 쌍 개념 : 해시.

대부분의 Perlers가 KVP에 대해 생각할 때, 그들은 "해시"라고 생각합니다. 그러나 Perl 배열이 1) 목록, 2) 대기열 및 3) 스택 인 방식에 대해 생각해 보면 구현이 개념과 정확하게 일치하지 않는다는 것을 알 수 있습니다. 나는 이미 List::Pairwise을 발견 할 때까지

나는, 내가 CPAN에 업로드 의미 내 자신의 라이브러리를 만들 수 있도록 해시 외부의 방식으로을 쌍을 치료하는 필요성을 보았다.

(내 "해시 접합"방법이 보이지 않는다 물론 ...) List::Pairwise를 사용 어쨌든

, 당신은 단순히

use List::Pairwise qw<grepp>; 
my %failed_s = grepp { $b eq 'failed' } %strings; 

나는 정보 광고 사람 때처럼 느낄 것 나는 "얼마나 간결한 지보세요!"라고 말합니다.

3

맵 + grep 콤보가 더 깨끗하다고 ​​생각합니다.

my %failed_s = 
    map { $_ => $strings{$_} } 
    grep { $strings{$_} eq 'failed' } 
    keys(%strings); 

그러나 그렙지도를 사용하여 구현 될 수 있기 때문에

, 그냥지도를 사용하여 수행 할 수 있습니다

my %failed_s = 
    map { $_ => $strings{$_} } 
    map { $strings{$_} eq 'failed' ? $_ :() } 
    keys(%strings); 

.

my %failed_s = 
    map { $strings{$_} eq 'failed' ? ($_ => $strings{$_}) :() } 
    keys(%strings); 

당신이 가진 문제는 아무 것도 반환 할 의도가 없을 때 거짓으로 돌아가는 것입니다.

+0

감사합니다. – Thomas