my $source = { f1 => 'garbage', f2 => 'more garbage', f3 => 'important data', f4 => { this => 'sub hash', is => 'garbage' }, f5 => { f6 => 'more important data', f7 => { more => 'garbage', f8 => 'important data', }, f9 => 'garbage', }, f10 => [ 'important', 'data' ], f11 => [ 'more', 'garbage' ] }; #### my $filter = { f3 => 1, f5 => { f6 => 1, f7 => { f8 => 1 } }, f10 => 1 }; #### my $output = { f3 => 'important data', f5 => { f6 => 'more important data', f7 => { f8 => 'important data', } }, f10 => [ 'important', 'data' ], }; #### sub hash_filter { my $source = shift; my $filter = shift; my %output; foreach ( keys %$filter ) { if ( exists $source->{$_} ) { if ( ref $filter->{$_} eq 'HASH' ) { croak "bad filter: on '$_', expected HASH\n" unless ( ref $source->{$_} eq 'HASH' ); $output{$_} = hash_filter( $source->{$_}, $filter->{$_} ); } else { $output{$_} = $source->{$_}; } } } return \%output; }