my %hash = ( 'key1' => [1, 20, 3], 'key2' => [1, 30, 4, 7], 'key3' => [1, 9, 8], 'key4' => [1, 9, 17], 'key5' => [1, 9, 17], ); my %rev_hash; while(my ($k, $v) = each %hash) { push @{$rev_hash{$_}}, $k for @$v; } #### $_ = join ' ', sort @$_ for values %rev_hash; my %inv_hash; while(my ($k, $v) = each %rev_hash) { push @{$inv_hash{$v}}, $k; } #### $_ = join ' ', sort {$a<=>$b} @$_ for values %inv_hash; my %revinv_hash = reverse %inv_hash;