in reply to substr in nested foreach loop

#HETATM 1562 O HOH 189 48.728 50.544 -16.104 my $num = qr{-?\d+\.\d+}; my $coordinate = qr{\s+($num)\s+($num)\s+($num)\s*$}; sub get_coordinates_for { my $filename = shift; my @coordinates = (); if (open $FH, $filename) { my $linecounter = 0; while (my $line = <$FH>) { $linecounter++; if ($line =~ m{$coordinate}) { my ($x , $y , $z) = ($1 , $2 , $3); push @coordinates , [$x , $y , $z]; } else { warn "[$filename : $linecounter] invalid lineformat!\n +"; } } close $FH; } else { die "failed to open $filename for reading($!)\n"; } return \@coordinates; } my $file1 = shift @ARGV; my $file2 = shift @ARGV; my $coordinates1_ref = get_coordinates_for($file1); my $coordinates2_ref = get_coordinates_for($file2); # calculate the results: foreach my $coordinate1 ( @$coordinates1_ref ) { my ($x , $y , $z) = @$coordinate1; foreach my $coordinate2 (@$coordinates2_ref) { my ($a , $b , $c) = @$coordinate2; my $distance = sqrt( ($x-$a)**2 + ($y-$b)**2 + ($z-$c)**2 ); print "distance ($x,$y,$z) to ($a,$b,$c) = $distance\n"; } }

Replies are listed 'Best First'.
Re^2: substr in nested foreach loop
by codeacrobat (Chaplain) on May 22, 2006 at 22:35 UTC
    A nice way to parse the coordinates is using Regexp::Common.
    use Regexp::Common; ... my $num = $RE{num}{real}; my ($x, $y, $z) = ($1, $2, $3) if $line =~ /($num) ($num) ($num)\s*$/;
      :D thank you.
      Isn't the behavior of "my" with an "if" modifier unspecified? I think
      my ($x, $y, $z) = ($line =~ /($num) ($num) ($num)\s*$/);
      would do what you want here. If it doesn't match all three variables will be undefined.
        okay, thank you.
Re^2: substr in nested foreach loop
by sarani (Sexton) on May 23, 2006 at 04:07 UTC
    Oh wow, that is as smooth as silk.. thank you muchly!