2013-09-06 30 views
6

Ich habe einen Hash von Hash, den ich filtern muss. Ich habe herausgefunden, wie man nachschlagen kann, aber es hat meine Frage nicht beantwortet.Einen Hash von Hash in Perl filtern

sagen, dass ich einen Hash Hash so haben:

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", 
    }, 
); 

ich sagen lässt ich die townfolks alle von Springfield möchten. Ich möchte den gleichen Hash von Hash in Ausgabe ohne die Außenseiter.

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

Es scheint albern, aber kann nicht herausfinden, wie man die struture filtert. Das Ziel wäre, nach Filterung auf alle Leute im Springfield zu iterieren.

Ich habe natürlich etwas Forschung und das nächste, was ich kam, ist Hash-Slices. Aber sie scheinen unheimlich.

Antwort

10

Als erstes müssen Sie die Schlüssel der Elemente, die Sie entfernen möchten, finden:

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

Sie sie dann löschen:

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

Oder eine Hash-Scheibe mit:

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

In dem 'grep' Sie die Behandlung von Strings ('keys% HoH') als HashRefs. – ThisSuitIsBlackNot

+0

@ThisSuitIsBlackNot, Fest. – ikegami

+2

Wie immer, sauberer und eleganter als die Lösung, an der ich arbeitete. Ich kann mir vorstellen, dass du das Zeug im Schlaf schreiben kannst. – ThisSuitIsBlackNot

4

Wenn Sie grep oder map durch Hashes benötigen, dann können Sie darüber nachdenken Verwenden Sie grepp oder mapp von List::Pairwise. Vorteil ist, dass die ursprüngliche Hash-Variable im grep/map-Codeblock nicht mehr erwähnt werden muss, damit sie "funktionaler" wird. So könnte Ihr Problem wie dieses Problem gelöst werden:

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/); 
} 

irgendeine Verwenden der Löschoption Sie Ihre Antwort bekommen ...