in reply to Breaking a Loop

You can call a subroutine in the middle of the loop. When it returns, loop execution will continue.

Replies are listed 'Best First'.
RE: Re: Breaking a Loop
by Anonymous Monk on Oct 10, 2000 at 22:39 UTC
    Hi guys, thanks for the speedy reply. The problem i guess is that i only want the subroutine, or array sorted once, and it isnt defined until the END of the loop.. lemme attach the code, and hopefully it will help
    #!/usr/local/bin/perl # Author: Dipul Patel # This Perl Script takes a home site chosen by the user, then calcula +tes # the distance from that home site to every site in the system and pr +ints # in a HTML table. #--------------------------------------------------------------------- # Process information for main site #--------------------------------------------------------------------- $lat_long = "/tmp/sitesLL"; $filepath = "/data1/PHL/neighbors"; $query_string = $ENV{'QUERY_STRING'}; @search = split(/&/,$query_string); @info = split(/=/, $search[0]); @siteinfo = split(/-/, $info[1]); print "Content-type: text/html\n\n"; #read in lat and long file open(LL, $lat_long); @lat_long = <LL>; close(LL); #Get long,lat,g,h,j for main site @dataline = grep /^$siteinfo[0]/, @lat_long; @dataparse = split(/\|/, $dataline[0]); ($sitelat, $sitelong) = split(/,/, $dataparse[3]); $g = $dataparse[4]; $h = $dataparse[5]; $j = $dataparse[6]; #--------------------------------------------------------------------- # Process information for every other site, one at a time #--------------------------------------------------------------------- #open directory and get sites names opendir DIR, $filepath; @allfiles = grep !/^\.\.?$/, readdir DIR; closedir DIR; @allfiles = sort @allfiles; $totalsite=@allfiles; @allfiles2=@allfiles; foreach $site(@allfiles) { chomp $site; @frst = split(/[a-z][a-z]/, $site); @cell = split(/[A-Z]/, $frst[1]); push(@othersiteinfo, $cell[0]); } #Open assiociated neighbor list file open(IN, "$filepath/$siteinfo[1]"); @data=<IN>; close(IN); #get sector numbers for neighbors foreach $line(@data){ #chomp $line; @information = split (/\|/, $line); push (@neighbor,$information[1]); } $n=-1; $temphigh = 0; while($n<$totalsite){ $n++; @dataline2 = grep /^$othersiteinfo[$n]/, @lat_long; @dataparse2 = split(/\|/, $dataline2[0]); ($sitelat2, $sitelong2) = split(/,/, $dataparse2[3]); $g2 = $dataparse2[4]; $h2 = $dataparse2[5]; $j2 = $dataparse2[6]; #--------------------------------------------------------------------- # calculate distance from main site to other sites #--------------------------------------------------------------------- $a=($g2-$g)*($g2-$g); $b=($h2-$h)*($h2-$h); $c=($j2-$j)*($j2-$j); $abc=($a+$b+$c); $sqabc=sqrt($abc); $distance=(3960*$sqabc); $distance = sprintf "%1.2f", $distance; $distance2=$distance; $distance3=$distance; $distance4=$distance; if ($temphighval >= $temphigh){ $temphigh=$temphighval; } if ( $distance > 10){ next; } # if ( $distance == 0){ # next; # } # The following code, first compares the sector number of the current + site to that of the neighbor list, # then it complies 2 arrays, one with all the neighbors, the other ar +ray with the other sites. $element = $othersiteinfo[$n]; if (grep {$_ eq $element} @neighbor) { @array3=($allfiles[$n],$distance2); push (@test1, @array3); push (@highval, $distance2); } else{ @array2=($allfiles[$n],$distance); push (@test2, @array2); } }#end whileloop my $done_sort=0; # or some more meaningful name while( $cond) { # probably some code here unless( $done_sort) { sort_the_array( @array); $done_sort=1; } # more code here } #create hash and sorted array for non-neighbors %distance=@test2; @sorted = sort { $distance{$a} <=> $distance{$b} } keys %distance; #extract sector numbers from sitename for use in hyperlinks. $k=0; @nonneighsect=@sorted; for ($h=0; $h<=$#nonneighsect; $h++) { $nonneighsect[$h] =~ s/\w{2}(\d{4})\w+/$1/; } #create hash and sorted array for neighbors %distance2=@test1; @sorted2 = sort { $distance2{$a} <=> $distance2{$b} } keys %distan +ce2; #extract sector numbers from sitename for use in hyperlinks. $j=0; @neighsect=@sorted2; for ($i=0; $i<=$#neighsect; $i++) { $neighsect[$i] =~ s/\w{2}(\d{4})\w+/$1/; } #-------------------- # the following code prints a table, with all the sites sorted first b +y neighbor, then distance. It also provides links # to automattically calculate distances for other sites, as well as ma +p them. #-------------------- print "<HTML>\n"; print "<HEAD><TITLE>Distance Tool</TITLE></HEAD>\n"; print "<TABLE BORDER=1 cellspacing=1 cellpadding=1 WIDTH =65%>\n"; print "<TR><TH Colspan = 4> Distance From $siteinfo[1] To:<TH>"; # print " <FONT SIZE=\-5><A HREF=\"http://www-mat.nextel.com/cg +i-bin/rfn-cgi/neighbormap2.cgi?frames=frames&site=$siteinfo[0]-$sitei +nfo[1]&rpt=Daily-Total&Lfactor=150000&sector=1\" target=_top>1</a></f +ont>\n"; # print " <FONT SIZE=\-5><A HREF=\"http://www-mat.nextel.com/cg +i-bin/rfn-cgi/neighbormap2.cgi?frames=frames&site=$siteinfo[0]-$sitei +nfo[1]&rpt=Daily-Total&Lfactor=150000&sector=2\" target=_top>2</a></f +ont>\n"; # print " <FONT SIZE=\-5><A HREF=\"http://www-mat.nextel.com/cg +i-bin/rfn-cgi/neighbormap2.cgi?frames=frames&site=$siteinfo[0]-$sitei +nfo[1]&rpt=Daily-Total&Lfactor=150000&sector=3\" target=_top>3</a></f +ont>\n"; print "<FONT SIZE =\-5>"; print "<TR><TH>Site<TH>Distance<TH>Neighbor<TH>Map(sector)\n"; foreach $site3 (@sorted2) { print " <TR><TD><FONT SIZE=\-5><A HREF=\"http://www-mat.ne +xtel.com/cgi-bin/rfn-cgi/distance.cgi?site=$neighsect[$j]-$site3\" >$ +site3<TD>$distance2{$site3}<TD align=center>YES</font>\n"; print " <TD align=center><FONT SIZE=\-5><A HREF=\"http://w +ww-mat.nextel.com/cgi-bin/rfn-cgi/neighbormap2.cgi?frames=frames&site +=$neighsect[$j]-$site3&rpt=Daily-Total&Lfactor=150000&sector=1\" targ +et=_top>1</a></font>\n"; print " <FONT SIZE=\-5><A HREF=\"http://www-mat.nextel.com +/cgi-bin/rfn-cgi/neighbormap2.cgi?frames=frames&site=$neighsect[$j]-$ +site3&rpt=Daily-Total&Lfactor=150000&sector=2\" target=_top>2</a></fo +nt>\n"; print " <FONT SIZE=\-5><A HREF=\"http://www-mat.nextel.com +/cgi-bin/rfn-cgi/neighbormap2.cgi?frames=frames&site=$neighsect[$j]-$ +site3&rpt=Daily-Total&Lfactor=150000&sector=3\" target=_top>3</a></fo +nt>\n"; $j++; } foreach $site2 (@sorted) { print " <TR><TD><FONT SIZE=\-5><A HREF=\"http://www-mat.ne +xtel.com/cgi-bin/rfn-cgi/distance.cgi?site=$nonneighsect[$k]-$site2\" +>$site2<TD>$distance{$site2}<TD align=center>NO</font>\n"; print " <TD align=center><FONT SIZE=\-5><A HREF=\"http://w +ww-mat.nextel.com/cgi-bin/rfn-cgi/neighbormap2.cgi?frames=frames&site +=$nonneighsect[$k]-$site2&rpt=Daily-Total&Lfactor=150000&sector=1\" t +arget=_top>1</a></font>\n"; print " <FONT SIZE=\-5><A HREF=\"http://www-mat.nextel.com +/cgi-bin/rfn-cgi/neighbormap2.cgi?frames=frames&site=$nonneighsect[$k +]-$site2&rpt=Daily-Total&Lfactor=150000&sector=2\" target=_top>2</a>< +/font>\n"; print " <FONT SIZE=\-5><A HREF=\"http://www-mat.nextel.com +/cgi-bin/rfn-cgi/neighbormap2.cgi?frames=frames&site=$nonneighsect[$k +]-$site2&rpt=Daily-Total&Lfactor=150000&sector=3\" target=_top>3</a>< +/font>\n"; $k++; } print "</FONT>"; print "</TABLE>\n"; print "</HTML>\n";
    now, what i want, is where it says
    if ( $distance > 10){ next; }
    i want the 10 to be replaced with the highest value of the array defined at the end of the loop:
    if (grep {$_ eq $element} @neighbor) { @array3=($allfiles[$n],$distance2); push (@test1, @array3); push (@highval, $distance2); }
    But.. that array is added to everytime the loop runs, and i need the highest value from it when it is complete, so i can specify the largest distance to map. I hope this helps.
    Dipul Patel
      So you don't want to sort the array, you want to find the max value in it. So write a subroutine to find the max value in your array and call that (just like chromatic suggested!)
      use strict; # ALWAYS!!!!!! # MaxElementInArray( @array ) sub MaxElementInArray { my $max = shift; my $next; $max = $next > $max ? $next : $max while $next = shift; return $max; } # MaxElementInArrayRef( \@array ) sub MaxElementInArrayRef { my $array_ref = shift; my $index = $#$array_ref; my $max = $$array_ref[$index]; $max = $$array_ref[$index] > $max ? $$array_ref[$index] : $max while --$index >= $[; return $max; }
      Update: While examining your code in response to your statement below, I've noticed quite a few style issues: You don't use strict, you are not using CGI.pm, and you are not using subroutines to improve the readability (and maintainability) of your code. I strongly suggest you look into these things. As for your issue of trying to use a number before you have calculated it... this reveals a failure to plan before coding. Now I suspect you will need to re-write much of this code just to get things in a causal order.
        Right, but there is still the problem that the array isnt defined until the end of the loop and that the sub routine has to be called within the loop. I need the max value of the final completed array, and returned into the loop..:-\.. when i wrote a subroutine it kept running it before it was called within the loop, and i would never get the final max value until the very end of the loop, by which point it was too late. thanks
        Dipul Patel
      Oh yeah, i forgot to mention, this is my second week of learning perl hehe :). Adam, where exactly should i place the code you gave me? I dont understand where to put it, and where/which one to call. Thanks
      Dipul Patel
        You may wish to be aware of a rather serious security hole in this script. I have detailed it here. You should read perlsec to learn the basics of these issues, and I would also suggest picking up a copy of "CGI Programming with Perl, Second Edition", by O'Reilly Press.

        Cheers,
        Ovid

        Join the Perlmonks Setiathome Group or just go the the link and check out our stats.