Perl hash filtering

I have a hash hash that I need to filter. I found how to do a search, but he did not answer my question.

Say I have a hash hash:

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

Let me say that I want all the townspeople from the spring field. I want the same hash to be output without strangers.

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

Seems dumb but can't figure out how to filter struture. The goal would be to iterate all the people of the spring field after filtering.

Of course, I did some research, and the closest I got is the hash fragments. But they seem scary.

+6
source share
3 answers

First you need to find the keys of the elements you want to delete:

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

Then you delete them:

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

Or using a hash fragment:

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

If you need grep or map through hashes, you might consider using grepp or mapp from List :: Pairwise . The advantage is that there is no need to mention the original hash variable anymore in the grep / map code block, making it more functional. Therefore, your problem can be solved as follows:

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

Use any of the delete options, you will get an answer ...

0
source

Source: https://habr.com/ru/post/953332/


All Articles