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

Dear Masters,
How can I slice a hash given an array, such that after slicing it the original hash is shrinked (destructed). So, I mean how can I modify my code below
perl -MData::Dumper -e ' %hash = (a => 3, b=> 4, c=>1 ,d=>7); @sel = qw(b c); @nhash{@sel} = @hash{@sel}; print Dumper \%hash;'
So that finally the original %hash becomes:
$VAR1 = { 'a' => 3, 'd' => 7 };
Is there a quick way to do it?

---
neversaint and everlastingly indebted.......

Replies are listed 'Best First'.
Re: Slicing and Destructing a Hash
by Enlil (Parson) on Sep 02, 2005 at 03:32 UTC
    Something like so?
    use warnings; use strict; use Data::Dumper; my %hash = (a => 3, b=> 4, c =>1 ,d=>7); my @sel = qw(b c); my %nhash; @nhash{@sel} = delete @hash{@sel}; print Dumper \%hash; print Dumper \%nhash; __END__ $VAR1 = { 'a' => 3, 'd' => 7 }; $VAR1 = { 'c' => 1, 'b' => 4 };

    -enlil

Re: Slicing and Destructing a Hash
by xdg (Monsignor) on Sep 02, 2005 at 03:35 UTC

    See delete:

    perl -MData::Dumper=Dumper -le '%hash = ( a=>3, b=>4, c=>1, d => 7 ); +@ary = qw(b c); @nhash{@ary} = delete @hash{@ary}; print Dumper \%has +h; print Dumper \%nhash;' $VAR1 = { 'a' => 3, 'd' => 7 }; $VAR1 = { 'c' => 1, 'b' => 4 };

    -xdg

    Code written by xdg and posted on PerlMonks is public domain. It is provided as is with no warranties, express or implied, of any kind. Posted code may not have been tested. Use of posted code is at your own risk.

Re: Slicing and Destructing a Hash
by pg (Canon) on Sep 02, 2005 at 03:29 UTC

    Loop through the array, and delete.

    use Data::Dumper; use strict; use warnings; my %hash = (a => 3, b=> 4, c=>1 ,d=>7); my @sels = qw(b c); delete $hash{$_} foreach (@sels); print Dumper \%hash;

    Update: Enlil's way is obviously faster and more straight.

    use Data::Dumper; use Benchmark qw(timethese); use strict; use warnings; timethese(1000000, { 'loop' => \&s1, 'non-loop' => \&s2 }); sub s1 { my %hash = (a => 3, b=> 4, c=>1 ,d=>7); my @sels = qw(b c); delete $hash{$_} foreach (@sels); } sub s2 { my %hash = (a => 3, b=> 4, c=>1 ,d=>7); my @sels = qw(b c); delete @hash{@sels}; }

    Result:

    Benchmark: timing 1000000 iterations of loop, non-loop... loop: 10 wallclock secs ( 9.84 usr + 0.03 sys = 9.87 CPU) @ 10 +1276.08/s (n=1000000) non-loop: 8 wallclock secs ( 6.88 usr + 0.02 sys = 6.89 CPU) @ 14 +5116.82/s (n=1000000)