#! perl -slw use strict; use Carp; use Data::Dump qw[ pp ]; sub hmap (&@) { our( $a, $b ); my $code = shift; croak "Even sized list or hash ref required" if @_ & 1 and not @_ == 1 && ref( $_[0] ) =~ m[HASH]; @_ = %{ $_[0] } if @_ == 1; my @rv; while( @_ ) { local( $a, $b ) = splice( @_, 0, 2 ), my $rv = $code->( $a, local $_ = $b ); push @rv, $rv ? ( $a, $rv ) : (); } wantarray ? @rv : { @rv }; } sub hgrep (&%) { our( $a, $b ); my $code = shift; croak "Even sized list or hash ref required" if @_ & 1 and not @_ == 1 && ref( $_[0] ) =~ m[HASH]; @_ = %{ $_[0] } if @_ == 1; my @rv; while( @_ ) { local( $a, $b ) = splice( @_, 0, 2 ); my $rv = $code->( $a, local $_ = $b); push @rv, $rv ? ( $a, $b ) : (); } wantarray ? @rv : { @rv }; } my %h = ( 'a' .. 'j', 's' .. 'z' ); pp 'start: ', \%h; my %r1 = hmap{ ++$b } %h; pp 'incr values: ', \%r1; my $r2 = hmap{ ++$_ } %r1; pp 'and again: ', $r2; my %h3 = hmap{ ++$_[1] } $r2; pp 'and once more: ', \%h3; my %s = hgrep{ $a le 'm' } %h; pp 'filter keys le m: ', \%s; my $t = hgrep{ length $b > 1 } \%h3; pp 'filter values longer than 1 char: ', $t; print "\n-----------\n"; my %old = ( '1' => { 'nick' => 'rbush', 'bday' => '3/12/1965', 'phone' => '5551212' }, '5' => { 'nick' => 'fred', 'bday' => '5/01/1972', 'phone' => '1112300' }, '11'=> { 'nick' => 'joan', 'bday' => '1/02/2033', 'phone' => '123456789' }, ); my %new = hmap { exists $b->{ nick } && $b->{ nick } =~ m[^(?:rbush|fred)$] ? ( $a => scalar hgrep{ $a =~ m[^(nick|phone)$] } $b ) : () } \%old; pp \%new; __END__ c:\test>hmap ( "start: ", { a => "b", c => "d", e => "f", g => "h", i => "j", "s" => "t", u => "v", w => "x", "y" => "z" }, ) ( "incr values: ", { a => "c", c => "e", e => "g", g => "i", i => "k", "s" => "u", u => "w", w => "y", "y" => "aa" }, ) ( "and again: ", { a => "d", c => "f", e => "h", g => "j", i => "l", "s" => "v", u => "x", w => "z", "y" => "ab" }, ) ( "and once more: ", { a => "e", c => "g", e => "i", g => "k", i => "m", "s" => "w", u => "y", w => "aa", "y" => "ac" }, ) ( "filter keys le m: ", { a => "b", c => "d", e => "f", g => "h", i => "j" }, ) ( "filter values longer than 1 char: ", { w => "aa", "y" => "ac" }, ) ----------- { 1 => { nick => "rbush", phone => 5551212 }, 5 => { nick => "fred", phone => 1112300 }, }