use Data::Dumper; my $h = { 1 => { nick => 'rbush', phone => '5551212', bday => '3/12/1965', }, 3 => { nick => 'ernest', phone => '5553300', bday => '3/12/1971', }, 5 => { nick => 'fred', phone => '1112300', bday => '5/01/1972', }, }; sub hmap { my ($h, $code) = @_; return undef unless defined $h; my $rv = {}; while (my ($k, $v) = each %$h) { my $x = &$code($k, $v); $rv->{$k} = $x if (defined $x); } return $rv; } my $new = hmap $h, sub { $_[1]->{nick} =~ /rbush|fred/ ? $_[1] : undef }; my $new2 = hmap $h, sub { return hmap $_[1]->{nick} =~ /rbush|fred/ ? $_[1] : undef, sub { $_[0] =~ /nick|phone/ ? $_[1] : undef } }; print "new = " . Dumper ($new) . "\n"; print "new2 = " . Dumper ($new2) . "\n";