use Deep::Hash::Utils qw(reach nest deepvalue); sub hash_filter { my ($source, $filter) = @_; my %rc; while (my @l = reach($filter)) { pop @l; if (defined( my $source_val = deepvalue($source, @l) ) ) { # hint: work around nest behavior on even vs odd key count nest(\%rc, @l)->{ $l[$#l] } = $source_val; } } \%rc; }