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

Say I have a table which has values in two columns :- Column1 = $var1 and Column2 = $var2 (note they are both chromosome coordinates so they are bound to be repeated in different columns sometimes).Now I want to store them in a hash such that there is only one instance of $val1 and $val2 in both the keys and values of that hash. How can I achieve it. This is what I have tried so far but it does not works :- Any help would be appreciated

use strict; use warnings; while(<>){ my @val = split/\t/; if (exists $hash_chr{$val[$#val]}){ next; } else{ $hash_chr{$val[0]}=$value[$#val]; } }

Replies are listed 'Best First'.
Re: hash with both values and keys unique to each other
by toolic (Bishop) on Jul 12, 2012 at 17:07 UTC
    A reply falls below the community's threshold of quality. You may see it by logging in.
Re: hash with both values and keys unique to each other
by locked_user sundialsvc4 (Abbot) on Jul 12, 2012 at 20:47 UTC

    If you need to ensure that both hash-keys and hash-values are unique, then you probably need to use two hashes.   The second hash should contain an entry for every value that’s been used in the first one:   the associated value (in the second hash) doesn’t matter, as we only care whether-or-not the key (in the second hash) exists.

    if ( (!exists($$hash1{$key} && (!exists($$hash2{$value}) ) { $$hash1{$key} = $value; $$hash2{$value} = 1; // DON'T CARE } else ... // (KEY AND/OR VALUE IS NOT UNIQUE...)

    Note that $$hash{$key} is equivalent to $hash->{$key} ... take your pick.

Re: hash with both values and keys unique to each other
by Anonymous Monk on Jul 12, 2012 at 17:57 UTC

    Assuming your question is "How to keep the values of a hash unique?", the answer is, well, two hashes:

    my (%hash, %rhash); while (<>) { chomp; my ($key, $val) = split(/\t/, $_, 2); next if (exists $hash{$key} or exists $rhash{$val}); $hash{$key} = $val; $rhash{$val} = 1; }

    Of course, there will be some manual housekeeping of the second hash. You could make it look nicer by creating an object that mimics a hash.

      This is how I was able to do it. But it might not be a generalized solution

      $seen{$chr1}++; $seen{$chr2}++; if (($seen{$chr1}>1)||($seen{$chr2}>1)){ next; } else{ $hash_chr{$chr1}=$chr2; }

        Since your structure is

        loop { if (condition) { next; } # no else! other code; }

        You don't actually need the else block. Removing it will make your code look quite a bit more clean.

Re: hash with both values and keys unique to each other
by Anonymous Monk on Jul 12, 2012 at 17:03 UTC

    Say I have a table which has values in two columns :- Column1 = $var1 and Column2 = $var2 (note they are both chromosome coordinates so they are bound to be repeated in different columns sometimes)

    Are they also pumpkins?

    How do I post a question effectively?

      Are they also pumpkins? LoL
      Perhaps what he wants is:
      to have all keys unique(which will be an obvious with a hash
      and
      to have all values in that hash unique
      and intersection of keys and values is null set.