I have a hash of hash that I need to filter. I did find how to do a lookup but it did not answer my question.
Say I have a hash of hash like that :
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 lets say I want all the townfolks from springfield. I want the same hash of hash in output without the outsiders.
my %HoH = (
flintstones => {
husband => "fred",
pal => "barney",
town => "springfield"
},
simpsons => {
husband => "homer",
wife => "marge",
kid => "bart",
town => "springfield",
},
);
It seems silly but can't figure out how to filter the struture. The goal would be to iterate on all the people of springfield after filtering.
I of course did some research and the closest thing I came by is hash slices. But they seem scary.
For example we can sort the hash first by the Position value, and among the entries with the same Position value we can sort by the value of the Max field. In order to do this we will use the following expression: my @maxed = sort { $data->{$a}{Position} <=> $data->{$b}{Position}
Perl Hash Accessing To access single element of hash, ($) sign is used before the variable name. And then key element is written inside {} braces.
undef $hash{$key} and $hash{$key} = undef both make %hash have an entry with key $key and value undef . The delete function is the only way to remove a specific entry from a hash. Once you've deleted a key, it no longer shows up in a keys list or an each iteration, and exists will return false for that key.
Perl hash question: How do I traverse the elements of a hash in Perl? Answer: There are at least two ways to loop over all the elements in a Perl hash. You can use either (a) a Perl foreach loop, or (b) a Perl while loop with the each function.
You first need to find the keys of the elements you want to remove:
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 slice:
delete @HoH{ grep { $HoH{$_}{town} eq 'springfield' } keys(%HoH) };
If you need to grep
or map
through hashes, then you can consider to use grepp
or mapp
from List::Pairwise. Advantage is that there's no need to mention the original hash variable anymore in the grep/map code block, making it more "functional". So your problem could be solved like this:
use List::Pairwise qw(grepp);
%HoH = grepp { $b->{town} eq 'springfield' } %HoH; # $a is the current key, $b is the current value
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With