august3 has asked for the wisdom of the Perl Monks concerning the following question:

Hi I am not sure how I can do this. I have a hash table with multiple keys mapping to same value. I would like extract the keys with same value. could anyone help me. Thanks Augustine
  • Comment on How to extract keyvalue pairs with duplicate values

Replies are listed 'Best First'.
•Re: How to extract keyvalue pairs with duplicate values
by merlyn (Sage) on Sep 28, 2004 at 14:49 UTC
    You could build up a reverse hash with arrayrefs, then count the length of those:
    my %forward_hash = (... your hash...); ## accumulate the reverse mapping my %reverse_hash; while (my($k, $v) = each %forward_hash)) { push @{$reverse_hash{$v}}, $k; } ## now see if there are dups: while (my($k, $v) = each %reverse_hash)) { my @vals = @$v; next unless @vals > 1; # skip single values print "value $k is shared by keys @vals\n"; }

    -- Randal L. Schwartz, Perl hacker
    Be sure to read my standard disclaimer if this is a reply.

Re: How to extract keyvalue pairs with duplicate values
by borisz (Canon) on Sep 28, 2004 at 14:53 UTC
    This code build a new hash with the values as keys and collect all keys that point to this value.
    my %h = ( a => 10, b => 10, c => 'd', e => 'd', f => 'a', ); my %x; while ( my ( $k, $v ) = each %h ) { push @{ $x{$v} }, $k; } __END__ $x = { 'a' => [ 'f' ], '10' => [ 'a', 'b' ], 'd' => [ 'e', 'c' ] };
    If you just want to remove the duplicates try:
    my %n = reverse %h; %n = reverse %n;
    Boris
Re: How to extract keyvalue pairs with duplicate values
by pelagic (Priest) on Sep 28, 2004 at 14:59 UTC
    Well Mister merlyn was faster ...
    anyway:
    use strict; my %hash = ( 1 => 'a' , 2 => 'b' , 3 => 'c' , 4 => 'b' , 5 => 'e' , 6 => 'b' , 7 => 'a' , 8 => 'z' ); my %values_with_multiple_keys = (); foreach my $k (keys %hash) { push @{ $values_with_multiple_keys{$hash{$k}} }, $k; } foreach my $m (keys %values_with_multiple_keys) { if (scalar @{$values_with_multiple_keys{$m}} > 1) { print "$m is referenced by: ", join ', ', @{$values_with_multi +ple_keys{$m}}, "\n"; } } ___OUTPUT___ a is referenced by: 7, 1, b is referenced by: 6, 2, 4,

    pelagic
      Hi everybody Thanks for helping me. Augustine
        Hello Augustine!
        it's now 3 weeks ago but you are very welcome anyway!

        pelagic
Re: How to extract keyvalue pairs with duplicate values
by Limbic~Region (Chancellor) on Sep 28, 2004 at 14:52 UTC
    august3,
    Your wording leaves a fair amount to be desired. I can see at least two interpretations:
    • Given a value, list all corresponding keys
    • Produce a list of values that have multiple keys
    The first one is easy:
    my @keys = grep { $hash{$_} eq 'value' }keys %hash;
    The second is just a bit more work:
    my %value; push @{ $value{ $hash{$_} } }, $_ for keys %hash; for ( keys %value ) { if ( @{ $value{$_} } > 1 ) { print "$_ :\n"; print "\t$_\n" for @{ $value{$_} }; } }

    Cheers - L~R