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

I am trying to match an array with the related value in the hash. Hash and array are opened and print fine but I can only get the match for one line not the complete array. Please help, I'm completely stuck and I keep hitting the same problem no matter how I write the rest.

my $Start_rank; my @b; my $line2; my %hash; my $Rank; my $info; while (<INFILE>) { my $line=$_; $line=~s/\s$//; chomp($line); my @a; #my @a=split/\t/,$line; ($Rank, my $id, my $C, my $Position) = split /\t/, $line; next unless $Rank=~/\d+/; $info = $id . "\t" . $C . "\t" . $Position; $hash{$Rank}= $info; } while (<INFILE2>) { $line2=$_; $line2=~s/\s$//; chomp($line2); my @b=split/\t/,$line2; next unless $b[0]=~/\d+/; $Start_rank = $b[1]; while (($Rank, $SNP_info) = each (%hash)) { foreach ($line2) { if ($Start_rank eq $Rank ) { print "$Start_rank\t$info\t$b[2]\t$b[3]\t$b[4]\t$b[5]\t$b[6]\t$b[7]\t$ +b[8]\t$b[9]\n"; } else {print "no match\n"; } } }}

I should get ~60 matches, instead I get one. Thank you for anything you can suggest.

Replies are listed 'Best First'.
Re: match loop failure
by toolic (Bishop) on Jun 08, 2011 at 17:09 UTC
    Without you showing any input data, actual output data and expected data, it is hard to give specific advice. After neatening up your code with perltidy, one really suspicious line is:
    foreach ($line2) {
    Since $line2 is a scalar, the foreach loop will only loop (at most) once.

    Generic advice:

      Apologies it was a first post. You were correct about the scalar. Thanks for your help.

Re: match loop failure
by jwkrahn (Abbot) on Jun 08, 2011 at 18:23 UTC

    It looks like you want something like this:

    my %hash; while ( <INFILE> ) { ( my $line = $_ ) =~ s/\s+$//; my ( $Rank, $id, $C, $Position ) = split /\t/, $line; next unless $Rank =~ /\d/; $hash{ $Rank } = "$id\t$C\t$Position"; } while ( <INFILE2> ) { ( my $line = $_ ) =~ s/\s+$//; my @b = split /\t/, $line; next unless $b[ 0 ] =~ /\d/; my $Start_rank = $b[ 1 ]; if ( exists $hash{ $Start_rank } ) { print join( "\t", $Start_rank, $hash{ $Start_rank }, @b[ 2 .. +9 ] ), "\n"; } else { print "no match\n"; } }

      After correcting the foreach scalar to @b I was going through each of the 200,000 keys in my hash (creating a 20GB output file). Using your exist correction makes the script much quicker! Thank you!