use strict; use warnings; use Data::Dumper; my %hash = ( apple => 'red', ball => 'red', lemon => 'yellow', lime => 'green', grass => 'green', ); my %rev; #= version 1 %rev=(); for my $value (values %hash) { $rev{$value}=[ grep { $hash{$_} eq $value } keys %hash ]; } print Dumper \%rev; #= version 2 %rev=(); while (my ($k,$v) = each %hash) { push @{ $rev{$v} }, $k ; } print Dumper \%rev; #= version 2b # not really shorter under strict ... %rev=(); my ($k,$v); push @{ $rev{$v} } , $k while ( ($k,$v) = each %hash); print Dumper \%rev; #= version 2c # hmm maybe finally a good application of builtin pkgvars $a and $b ;) # VIVA LA AUTOVIVICACION! 8 ) %rev=(); push @{ $rev{$b} } , $a while ( ($a,$b) = each %hash); print Dumper \%rev; __END__ #OUTPUT $VAR1 = { 'green' => [ 'grass', 'lime' ], 'red' => [ 'apple', 'ball' ], 'yellow' => [ 'lemon' ] }; ...