Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked
 
PerlMonks  

hash with both values and keys unique to each other

by perlkhan77 (Acolyte)
on Jul 12, 2012 at 16:56 UTC ( #981440=perlquestion: print w/ replies, xml ) Need Help??
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]; } }

Comment on hash with both values and keys unique to each other
Download Code
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.
Re: hash with both values and keys unique to each other
by toolic (Chancellor) on Jul 12, 2012 at 17:07 UTC
      Guys this is just a pseudocode to make you understand what the problem really is.

        Following is the real code :

        use strict; use Time::HiRes; my $start_time = [Time::HiRes::gettimeofday()]; my (@coordinates,%hash_chr,%HOA,%HOH,%hash_line) = (); open FILE,"GmGm.recent.gff"; while(my $line=<FILE>){ chomp $line; my %seen = (); if($line=~/^(Gm\d{1,})\trecent_duplication\tsyntenic_region\t(\d{1,})\ +t(\d{1,})\t.*\tID\=\w{1,}_Gm\d{1,}\.(Gm\d{1,}.*)\;median_Ks=(.*)\;mat +ches\=(Gm\d{1,}\:\d{1,}\.\.\d{1,})/) { my $chr1 = "$1:$2..$3"; my $ks_val = $5; my $chr2 = $6; if ((exists $hash_chr{$chr2})&&($ks_val > 0.4)){ next; } else{ $hash_chr{$chr1}=$chr2; } } } close FILE;

        And this is how the file looks like

        Gm01 recent_duplication syntenic_region 170877 269340 1 +79 - . ID=A_Gm01.Gm08.2.-;median_Ks=0.1101;matches=Gm08:4628 +8465..46349001 Gm08 recent_duplication syntenic_region 46288465 46349001 + 179 - . ID=B_Gm01.Gm08.2.-;median_Ks=0.1101;matches=Gm01: +170877..269340

        There are some standard ways to ask questions that elicit positive responses.

        You can use pseudo-code. If you do so, under no circumstances should it look like something a noob whipped up without any thought. One good way to do this is not to write it in any programming language you know. However, even here, variable names must be followable.

        Or you can use a short example of your code. It must be compilable (unless your question is "why doesn't this compile?"). It must be runnable. And it must produce the error scenario you describe. This makes it easy for those who may have an idea on how to help you to actually, you know, help. They can load your code into their debugger, go at it line by line, and possibly give you some insight into your issue. It also helps if you follow some sort of coding standards. It doesn't have to be the One True Brace Style, but it has to be something consistent and has to lend itself to being readable to others. If this all means you need to heavily edit your code before posting, it will at least be obvious that you put some effort in to being helped, making it more likely others will help you. Or at least it won't look like a big ball of mud and that you put no effort into being helped.

        Of course, when you do all that, you'll start to find that you solve your own problem. It might be more work, but it'll solve your issue faster than waiting for some random monk to happen upon your node and take the challenge of helping you with a reply.

        Guys this is just a pseudocode to make you understand what the problem really is.

        Pseudocode with  use strict; use warnings; ?

        Might as well make it real code

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 sundialsvc4 (Monsignor) 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.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://981440]
Approved by ww
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others browsing the Monastery: (8)
As of 2014-08-29 20:14 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The best computer themed movie is:











    Results (288 votes), past polls