for my $key (keys %hash) { print "$key\n" if grep {$_ eq "banana"} @{ $hash{$key} }; } #### # convert my %hoh = map { $_ => { map {$_=>1} @{ $hash{$_} } } } keys %hash; # debug: inspect the converted data use Data::Dumper; print Dumper(\%hoh); # lookup my $search = "banana"; for my $key (keys %hoh) { print "$key\n" if $hoh{$key}{$search}; } #### # build inverse hash, if all values are unique my %inverse_hash; for my $key (keys %hash) { for my $val (@{ $hash{$key} }) { $inverse_hash{$val} = $key; } } # debug: inspect the converted data print Dumper(\%inverse_hash); # lookup is simple! print $inverse_hash{banana}, "\n"; #### # convert to "inverse" hash of arrays (in two steps) my %hoa; # first, build a hash of hashes # (this eliminates duplicates at both levels) for my $key (keys %hash) { for my $val (@{ $hash{$key} }) { $hoa{$val}{$key}++; } } # then, convert the second level of hashes to arrays for my $vals (values %hoa) { $vals = [sort keys %$vals]; } # debug: inspect the converted data print Dumper(\%hoa); # lookup print join(', ', @{ $hoa{banana} } ), "\n"