2013-09-06 10 views
6

Mam skrót mieszania, który muszę filtrować. Znalazłem sposób wyszukiwania, ale nie odpowiedziałem na moje pytanie.Filtrowanie skrótu mieszania w perlu

Say mam hash hash tak:

my %HoH = (
    flintstones => { 
     husband => "fred", 
     pal  => "barney", 
     town  => "springfield" 
    }, 
    jetsons => { 
     husband => "george", 
     wife  => "jane", 
     "his boy" => "elroy", 
    }, 
    simpsons => { 
     husband => "homer", 
     wife  => "marge", 
     kid  => "bart", 
     town  => "springfield", 
    }, 
); 

I powiedzmy, że chcę wszystkie townfolks z Springfield. Chcę mieć ten sam skrót mieszania na wyjściu bez osób postronnych.

my %HoH = (
    flintstones => { 
     husband => "fred", 
     pal  => "barney", 
     town  => "springfield" 
    }, 
    simpsons => { 
     husband => "homer", 
     wife  => "marge", 
     kid  => "bart", 
     town  => "springfield", 
    }, 
); 

Wydaje się głupie, ale nie może dowiedzieć się, jak filtrować struture. Celem byłoby powtórzenie wszystkich ludzi w Springfield po przefiltrowaniu.

Ja oczywiście zrobiłem trochę badań i najbliższa rzecz, którą przyszedłem to plasterki skrótu. Ale wydają się przerażające.

Odpowiedz

10

najpierw trzeba znaleźć klucze elementów, które chcesz usunąć:

grep { $HoH{$_}{town} eq 'springfield' } keys(%HoH) 

Następnie należy je usunąć:

delete $HoH{$_} for grep { $HoH{$_}{town} eq 'springfield' } keys(%HoH); 

lub za pomocą kawałek skrótu:

delete @HoH{ grep { $HoH{$_}{town} eq 'springfield' } keys(%HoH) }; 
+1

w katalogu 'ciągów grep' traktujesz ('keys% HoH') jako hashrefs. – ThisSuitIsBlackNot

+0

@ThisSuitIsBlackNot, Naprawiono. – ikegami

+2

Jak zawsze, czystszy i bardziej elegancki niż rozwiązanie, nad którym pracowałem. Wyobrażam sobie, że możesz pisać te rzeczy podczas snu. – ThisSuitIsBlackNot

4

Jeśli potrzebujesz grep lub map za pośrednictwem skrótów, możesz rozważyć użyj grepp lub mapp z List::Pairwise. Zaletą jest to, że nie trzeba już wspominać o oryginalnej zmiennej hash w bloku kodu grep/map, czyniąc ją bardziej "funkcjonalną". Więc problem można rozwiązać tak:

use List::Pairwise qw(grepp); 
%HoH = grepp { $b->{town} eq 'springfield' } %HoH; # $a is the current key, $b is the current value 
0
for my $key (keys %HoH) { 
delete $HoH{$key} if(!$HoH{$key}{town}); 
        (OR) 
delete $HoH{$key} if($HoH{$key}{town} !~ m/springfield/); 
} 

Użyj dowolnego jednego z opcję usuwania dostaniesz odpowiedź ...