Beefy Boxes and Bandwidth Generously Provided by pair Networks
Come for the quick hacks, stay for the epiphanies.
 
PerlMonks  

How to compare hash values to array values in Perl

by To_Bz (Novice)
on May 14, 2014 at 04:21 UTC ( [id://1085973]=perlquestion: print w/replies, xml ) Need Help??

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


I have two input files: table.txt and values.txt

table.txt looks like the following:

xanmn_chr09_0114-xanmn_chr09_0114 3346 xanmn_chr09_0129-xanmn_chr09_0129 3358 xanmn_chr09_0116-xanmn_chr09_0116 3348 xanmn_chr09_0127-xanmn_chr09_0127 3354

values.txt looks like this:
3346 1933 1371 1448 2762 1395

Then, I want to compare the second column of table.txt with the first column of values.txt. So, if they have the same number, for instance 3346, the script should return xanmn_chr09_0114-xanmn_chr09_0114 because xanmn_chr09_0114-xanmn_chr09_0114 corresponds to 3346.

This is my script:

open(FILE1, "<", table.txt) open(FILE2, "<", values.txt) my %ids2proteins=(); while(my $row = <FILE2>){ chomp $row; my @column = split(/\t/, $row); my $protein_number = $column[0]; while(my $line= <FILE1>){ chomp $line; my @fields = split(/\t/, $line); my ($ids,$proteins) = ($fields[0],$fields[1]); $ids2proteins{$ids} = $proteins; foreach my $keys(keys %ids2proteins){ my $values = $ids2proteins{$keys}; if($values eq $protein_number){ print "$keys => $protein_number"; }}}}


Everything works well until the if inside the foreach. I'm relatively new in Perl, and I think that I have a problem with the logic of the problem.

So, I will really appreciate the help.

Replies are listed 'Best First'.
Re: How to compare hash values to array values in Perl
by LanX (Saint) on May 14, 2014 at 04:30 UTC
    > Then, I want to compare the second column of table.txt with the first column of values.txt.

    you have 3 nested loops, this must be wrong.

    Just read table.txt ONCE (open,loop,close) into a big hash with the numbers (second-column) as keys.

    Then while reading values.txt check this hash (open,loop and test, close)

    2 unnested loops, that's all you need.

    HTH :)

    Cheers Rolf

    ( addicted to the Perl Programming Language)

    update

    corrected typo, thx Athanasius! :)

Re: How to compare hash values to array values in Perl
by NetWallah (Canon) on May 14, 2014 at 05:28 UTC
    Since you claim to be a "perl beginner" - kcott's (++) code may be a little esoteric.

    Here is somewhat simpler and more traditional code (with no module dependencies):

    use strict; use warnings; open(my $table, "<", "table.txt") or die "Cannot open Tables"; my %ids2proteins; while (<$table>){ chomp; my ( $protein, $nbr) = split ; next unless $nbr; $ids2proteins{$nbr} = $protein; } close $table; open(my $val, "<", "values.txt") or die "Cannot open Values"; while (<$val>){ chomp; next unless length $_ > 1; next unless my $prot = $ids2proteins{$_}; print "$prot => $_ \n"; } close $val;

            What is the sound of Perl? Is it not the sound of a wall that people have stopped banging their heads against?
                  -Larry Wall, 1992

      "Since you claim to be a "perl beginner" - kcott's (++) code may be a little esoteric."

      To NetWallah: Thanks for the ++; esotericism was not the intention.

      To To_Bz: If there was something in my original code you didn't understand, please feel free to ask; however, first see the clarification below.

      "Here is somewhat simpler and more traditional code (with no module dependencies):"

      The module (Inline::Files) was not intended for To_Bz's code; it was purely for my test.

      I was aiming to use (what appeared to be) the smaller file (values.txt) to create the hash; then selectively printing from (what appeared to be) the larger file (table.txt).

      As a clarification, here's the entire script I envisaged for To_Bz (correcting the open syntax errors and applying my lexical filehandle recommendation):

      #!/usr/bin/env perl -l use strict; use warnings; use autodie; open my $table, '<', 'table.txt'; open my $values, '<', 'values.txt'; my %vals = map { $_ => 1 } <$values>; print $_->[0] for grep { $vals{$_->[1]} } map { [ split / / ] } <$tabl +e>;

      [Note: autodie used in lieu of hand-crafting die messages for both open statements.]

      -- Ken

Re: How to compare hash values to array values in Perl
by kcott (Archbishop) on May 14, 2014 at 05:18 UTC

    G'day To_Bz,

    Welcome to the monastery.

    You can achieve that much more simply like this:

    my %vals = map { $_ => 1 } <FILE2>; print $_->[0] for grep { $vals{$_->[1]} } map { [ split / / ] } <FILE1 +>;

    I would, however, recommend you use lexical filehandles. See open for examples.

    Here's my test (in the spoiler):

    -- Ken

Re: How to compare hash values to array values in Perl
by vinoth.ree (Monsignor) on May 14, 2014 at 05:56 UTC

    Hi

    #!/usr/bin/env perl -l use strict; use warnings; use Data::Dumper; open(TABLE,"<","./table.txt") or die $!; my %Tables=(); my $eachline; while( $eachline=<TABLE>) { next if $eachline=~/^$/; chomp($eachline); my ($value,$key)= split (/\s+/,$eachline); $Tables{$key} = $value; } print Dumper \%Tables; open(VALUES,"<","./values.txt") or die $!; my $eachValue; while($eachValue=<VALUES>) { chomp($eachValue); if (exists $Tables{$eachValue}) { print $eachValue Matches in table.txt $Tables{$eachVal +ue}.qq(\n); } else { print "$eachValue not matched in table.txt file\n"; } }

    Update:Including input files.

    Table.txt
    xanmn_chr09_0114-xanmn_chr09_0114 3346 xanmn_chr09_0129-xanmn_chr09_0129 3358 xanmn_chr09_0116-xanmn_chr09_0116 3348 xanmn_chr09_0127-xanmn_chr09_0127 3354
    Values.txt
    3346 1933 1371 1448 2762 1395

    All is well
Re: How to compare hash values to array values in Perl
by LanX (Saint) on May 14, 2014 at 15:14 UTC
    If you are wise you'll ignore the spoon fed code others provided.

    Better to first try coding it with the hints given all by yourself!

    Cheers Rolf

    ( addicted to the Perl Programming Language)

      If you're wise you code for yourself, but if you're clever you don't stand in the way of people that are willing to do the coding for you (only joking of course).
Re: How to compare hash values to array values in Perl
by Lennotoecom (Pilgrim) on May 14, 2014 at 18:57 UTC
    maybe similar to given above
    use Inline::Files; $h{$a[1]} = $a[0] while @a = split /\s|$/, <TABLE>; exists $h{$_} and print "$h{$_}\n" while chomp($_ = <VALUES>); __TABLE__ xanmn_chr09_0114-xanmn_chr09_0114 3346 xanmn_chr09_0129-xanmn_chr09_0129 3358 xanmn_chr09_0116-xanmn_chr09_0116 3348 xanmn_chr09_0127-xanmn_chr09_0127 3354 __VALUES__ 3346 1933 1371 1448 2762 1395

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others cooling their heels in the Monastery: (2)
As of 2024-03-19 06:37 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found