how to put "if" within a loop

J

Jie

as you see below, I am trying to compare if a list of files have
common elements. The following code works. The problem is that for the
last two lines I need to manually write each array element. when the
array is long, it is much awkward.

is there a way to put the "if" inside a loop?

thank you very much!

Jie

==========my code============
@lists = ("A", "B", "C");
foreach $list (@lists) {
%{$list} = ();
open IN, " < $list.txt";
while (<IN>) {
$_ =~ /(rs\d+)\t([^\t]+)/;
${$list}{$1} = $2;
}
close IN;
}

foreach $SNP (%{$lists[0]}) {
if ( exists ${$lists[1]}{$SNP} && exists ${$lists[2]}{$SNP}) {
print OUT "$SNP\t${$lists[0]}{$SNP}\t${$lists[1]}{$SNP}\t${$lists[2]}
{$SNP}\n";
}
}
 
M

Mirco Wahab

Jie said:
is there a way to put the "if" inside a loop?
==========my code============
@lists = ("A", "B", "C");
foreach $list (@lists) {
%{$list} = ();
open IN, " < $list.txt";
while (<IN>) {
$_ =~ /(rs\d+)\t([^\t]+)/;
${$list}{$1} = $2;
}
close IN;
}

foreach $SNP (%{$lists[0]}) {
if ( exists ${$lists[1]}{$SNP} && exists ${$lists[2]}{$SNP}) {
print OUT "$SNP\t${$lists[0]}{$SNP}\t${$lists[1]}{$SNP}\t${$lists[2]}
{$SNP}\n";
}
}

Try (untested):

...
foreach my $SNP (%{$lists[0]}) {
print
$SNP,
join "\t",
map ${$lists[$_]}{$SNP},
grep exists ${$lists[$_]}{$SNP},
0 .. $#lists;
print "\n"
}
...



BTW: you should drop this code completely
and rewrite a small idiomatic solution
(only a few lines).

The symbolic refs render this code unmaintainable
and dangerous.

Regards

M.
 
M

Michele Dondi

@lists = ("A", "B", "C");

use strict;
use warnings;
foreach $list (@lists) {

my $list
%{$list} = ();
open IN, " < $list.txt";

# possibly better:
open my $in, '<', "$list.txt"
or die "something that includes $list and $!\n"
while (<IN>) {
$_ =~ /(rs\d+)\t([^\t]+)/;

# either
$var =~ /$rx/;
# or
/$rx/;
foreach $SNP (%{$lists[0]}) {

Are you sure you don't want keys() there?
if ( exists ${$lists[1]}{$SNP} && exists ${$lists[2]}{$SNP}) {
print OUT "$SNP\t${$lists[0]}{$SNP}\t${$lists[1]}{$SNP}\t${$lists[2]}
{$SNP}\n";
}
}

You can make your code slightly more agile:

# untested
my @lists = qw/A B C/;
for (@lists) {
open my $in, '<', "$_.txt"
or die "Can't open `$_.txt': $!\n";
/(rs\d+)\t([^\t]+)/ and ${$list}{$1}=$2 while <$in>;
}

for my $snp (keys %{$lists[0]}) {
print $out (join "\t", $snp, map ${$lists[$_]}{$snp}, 0..2), "\n"
if 2 == grep exists ${$lists[$_]}{$snp}, 1,2;
}


Michele
 
B

Brian McCauley

as you see below, I am trying to compare if a list of files have
common elements. The following code works. The problem is that for the
last two lines I need to manually write each array element. when the
array is long, it is much awkward.

is there a way to put the "if" inside a loop?

thank you very much!

Jie

==========my code============
@lists = ("A", "B", "C");

Why are you not declaring your variables?
foreach $list (@lists) {
%{$list} = ();

Why are you using symbolic references?
open IN, " < $list.txt";

Why are you using global filehandles?

Why are you using the 2-arg open?

All the above implies to me that you are learning to program in Perl4.

Perl5 has been around a long time now. There's really no reason to
learn Perl4. If you have a book or other resource that is teaching you
Perl4 programming techniques I suggest you burn it.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,776
Messages
2,569,603
Members
45,189
Latest member
CryptoTaxSoftware

Latest Threads

Top