Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw

Hash slices

by Marcello (Hermit)
on Feb 17, 2004 at 12:53 UTC ( #329578=perlquestion: print w/replies, xml ) Need Help??

Marcello has asked for the wisdom of the Perl Monks concerning the following question:


Say I have a hash like this:
my %hash = ("NETWORK1" => "A", "NETWORK2" => "B", "TYPE1" => "C", "TYP +E2" => "D");
Now I want to create a new hash with only those keys/values where the key =~ m/^NETWORK/

So keys matching /^NETWORK/:
my %hashslice1 = ("NETWORK1" => "A", "NETWORK2" => "B");
And keys matching /^TYPE/:
my %hashslice2 = ("TYPE1" => "C", "TYPE2" => "D");
The problem is... how?
Two functions come to mind: grep and map, but I am not sure how to use those to get to hash slices above.


Replies are listed 'Best First'.
Re: Hash slices
by Roger (Parson) on Feb 17, 2004 at 12:59 UTC
    use strict; use warnings; use Data::Dumper; my %hash = ("NETWORK1" => "A", "NETWORK2" => "B", "TYPE1" => "C", "TYP +E2" => "D"); my %hashslice1 = map { /^NETWORK/ ? ($_,$hash{$_}) : () } keys %hash; print Dumper(\%hashslice1); my %hashslice2 = map { /^TYPE/ ? ($_,$hash{$_}) : () } keys %hash; print Dumper(\%hashslice2);

    Updated: solution 2
    use strict; use warnings; use Data::Dumper; my %hash = ("NETWORK1" => "A", "NETWORK2" => "B", "TYPE1" => "C", "TYP +E2" => "D"); my @keys = grep /^NETWORK/, keys %hash; my %hashslice1; @hashslice1{@keys} = @hash{@keys}; print Dumper(\%hashslice1); @keys = grep /^TYPE/, keys %hash; my %hashslice2; @hashslice2{@keys} = @hash{@keys}; print Dumper(\%hashslice2);
Re: Hash slices
by QM (Parson) on Feb 17, 2004 at 19:02 UTC
    While Roger gave you some solutions, I wonder if you really need a new hash, or if you just need to use the values once.

    You could get the values like this:

    my %hash = ( "NETWORK1" => "A", "NETWORK2" => "B", "TYPE1" => "C", "TYPE2" => "D"); my @networks = @hash{ grep /^NETWORK/, sort keys %hash };
    You could even pass the values into a function directly, instead of catching them in the array first. It just depends on what your goal is.

    Quantum Mechanics: The dreams stuff is made of

Re: Hash slices
by revdiablo (Prior) on Feb 17, 2004 at 19:16 UTC

    Roger has already provided a few solutions, and QM has a good answer, but here's another:

    my %newhash1 = map { $_=>$hash{$_} } grep { /^NETWORK/ } keys %hash;

    I'm not sure how all these compare in terms of speed, efficiency, etc. This is just how I'd do it for greatest clarity.

      I tried to find an elegant way to avoid map...grep, but only came up with this:
      my %hash2; map { $hash2{$_} = $hash{$_} if /^NETWORK/ } keys %hash;
      which is fancy-looking, non-map-in-a-void-context way of saying:
      my %hash2; { $hash2{$_} = $hash{$_} if /^NETWORK/ } foreach keys %hash;
      My rough check with Benchmark shows no difference between map...grep and map alone until the hash sizes were increased to force memory paging to disk.

      [I didn't check to see if anything was optimized away.]

      Quantum Mechanics: The dreams stuff is made of

        I tried to find an elegant way to avoid map...grep

        Roger's first solution actually does this in a pretty nice way. I added some formatting to [hopefully] make it more clear, but here's his code:

        my %hashslice1 = map { /^NETWORK/ ? ($_, $hash{$_}) : ( ) } keys %hash;

        Even still, I can see how mixing the selection of the keys with the hashification is a bit confusing, so that's why I gave a map {} grep {} solution that separates them.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://329578]
Approved by Roger
Front-paged by Roy Johnson
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others pondering the Monastery: (5)
As of 2020-05-27 23:34 GMT
Find Nodes?
    Voting Booth?
    If programming languages were movie genres, Perl would be:

    Results (162 votes). Check out past polls.