Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Filtering a hash of hash in perl

Tags:

hash

perl

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.

like image 605
rakwatt Avatar asked Sep 06 '13 14:09

rakwatt


People also ask

How do I sort hash hash in Perl?

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}

How do you access the elements of a hash in Perl?

Perl Hash Accessing To access single element of hash, ($) sign is used before the variable name. And then key element is written inside {} braces.

How do I remove a key from a hash in Perl?

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.

How do I traverse a hash in Perl?

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.


2 Answers

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) };
like image 150
ikegami Avatar answered Oct 24 '22 07:10

ikegami


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
like image 23
Slaven Rezic Avatar answered Oct 24 '22 05:10

Slaven Rezic