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

I finally finished building my locator script the only thing I can't seem to get to go it a sort of the output by distance actually $km looking for some wisdom on this one.
$count = 0; open(FILE, "herbalarea.pl") || die "I can't open that because: $!\ +n"; while(<FILE>) { chop; @all = split(/\n/); foreach $line (@all) { local($hStoreID, $hStoreName, $hStoreUserName, $hStorePassword, $h +StoreMCRSPassword, $hStoreCity, $hStoreProv, $hStoreAdd, $hStoreAdd2, + $hStorePC, $hStoreCountry, $hStoreEmail, $hStorePhone, $hStoreType, +$hStoreLatitude, $hStoreLongitude, $hStoreFirstName, $hStoreLastName, + $hStoreHPhone, $hStoreCPhone, $hStoreEmail2, $hStoreOwner, $hStoreAd +min, $hStoreAdmin2, $hStoreAdmin3, $hStoreActive, $hStoreWeb, $hStore +Lang, $hStoreDesc, $hStoreShowMap, $hStoreComingSoonText, $hStoreComi +ngSoonTextFrench, $hStoreVanityName, $hStoreWebCreatedDate, $hStoreLa +stLogin, $hStoreLastEnabled, $hStoreManagerEmpID, $hStoreURL) = split +(/ /, $line); $lat2 = $hStoreLatitude; $lon2 = $hStoreLongitude; $lat1 = $lat1a; $lon1 = $lon1a; @L = (deg2rad($lat1), deg2rad(90 - $lon1)); @T = (deg2rad($lat2), deg2rad(90 - $lon2)); $km = great_circle_distance(@L, @T, 6378); if ($km < $distance) { $match = 1; $count ++; $area = "$hStoreName <BR> $hStoreAdd <br> $hStoreCity, $hStorePro +v $hStorePC\n"; $area1 = "$hStoreAdd $hStoreAdd2 $hStoreCity, $hStoreProv $h +StorePC\n"; $area2 = "$hStoreCity, $hStoreProv\n"; print " <table border=0 width=240 height=105 cellpadding=15 cellspacing=0 back +ground=\"http://pagelinx.com/herbalmagic/files/loc_bck.gif\"> <tr> <td style=\"font-size: 11px; color: #5D5D5D;\"> Store # <A HREF=\"javascript:change1('pic1','image$count')\">$area</A> +<BR>\n"; print "<div class=\"book\"> <A HREF=\"http://www.pagelinx.com/herbalmagic/form.php?center=$hStoreN +ame&address=$hStoreAdd&city=$hStoreCity&prov=$hStoreProv\" target=_pa +rent>Book Your Free Consultation</a> - KM $km</div></A></td> </tr> </table> \n"; } } }

Replies are listed 'Best First'.
Re: Sort output
by Jenda (Abbot) on May 07, 2009 at 00:24 UTC
    1. The while(<FILE>) { reads the file one line at a time so there is no need to split the $_ then. So the split to @all is superfluous.
    2. You should use chomp() not chop() if you want to remove the newline character. The thing is that the chop() removed one character, no matter what it is. So if the last line in the file doesn't end with a newline character, you will remove the last character of the line!
    3. You use a heluvalot of related variables there, maybe you should rather stick all this data into a hash. You will actually need to do that to be able to sort the items.
      while (<FILE>){ chomp; my %store;@store{Id Name Username Password ...} = split / /; $store{km} = ... push @stores, \%store; } foreach (sort {$a->{km} <=> $b->{km}} @stores) { print "...." }
    4. You stick the values of those variables into the URL without any escaping whatsoever! What if the data contain something that's special in URLs? Spaces, &s, #s, %, ... You should always make sure you escape all the data you print in whatever way necessary for the place you stick them at! (In this case have a look at CGI::Enurl for example.)

    Jenda
    Enoch was right!
    Enjoy the last years of Rome.

Re: Sort output
by jethro (Monsignor) on May 07, 2009 at 00:53 UTC

    Provided your list fits into memory, you could put everything you need into a hashofhashes (a hash of arrays would work too) with $km as the key:

    my %inarea; if ($km < $distance) { ... $inarea{$km}= {area=>$area, area1=>$area1, hStore=$hStore }; }

    Now we can sort it

    foreach my $km ( sort keys %inarea ) { print " <table ... $inarea{$km}{area}</A><BR> ...
      I'd really see how the solution works but evertime I try I cant get it to run like that woiuld you mind showing me how it would actually be put into the script. Thanks

        Please note Jenda's post, especially his point 4. You will get into problems if you don't sanitize the input. Also you should clean up your intendation

        I would have prefered if you had posted your last attempt and mentioned how it was not working. Then I could have shown you the bug and even how to find it. I'll give you more context, but I don't want to do the work of changing every single occurence of your many variables, this fine tuning you have to do yourself. Just add all the variables needed for the web page at the two places where I put '...' using the same syntax

        $count = 0; my %inarea; open(FILE, "herbalarea.pl") || die "I can't open that because: $!\ +n"; while(my $line= <FILE>) { chomp $line; local($hStoreID, $hStoreName, $hStoreUserName, $hStorePassword, $h +StoreMCRSPassword, $hStoreCity, $hStoreProv, $hStoreAdd, $hStoreAdd2, + $hStorePC, $hStoreCountry, $hStoreEmail, $hStorePhone, $hStoreType, +$hStoreLatitude, $hStoreLongitude, $hStoreFirstName, $hStoreLastName, + $hStoreHPhone, $hStoreCPhone, $hStoreEmail2, $hStoreOwner, $hStoreAd +min, $hStoreAdmin2, $hStoreAdmin3, $hStoreActive, $hStoreWeb, $hStore +Lang, $hStoreDesc, $hStoreShowMap, $hStoreComingSoonText, $hStoreComi +ngSoonTextFrench, $hStoreVanityName, $hStoreWebCreatedDate, $hStoreLa +stLogin, $hStoreLastEnabled, $hStoreManagerEmpID, $hStoreURL) = split +(/ /, $line); $lat2 = $hStoreLatitude; $lon2 = $hStoreLongitude; $lat1 = $lat1a; $lon1 = $lon1a; @L = (deg2rad($lat1), deg2rad(90 - $lon1)); @T = (deg2rad($lat2), deg2rad(90 - $lon2)); $km = great_circle_distance(@L, @T, 6378); if ($km < $distance) { $match = 1; $count ++; $area = "$hStoreName <BR> $hStoreAdd <br> $hStoreCity, $hStorePro +v $hStorePC\n"; $area1 = "$hStoreAdd $hStoreAdd2 $hStoreCity, $hStoreProv $h +StorePC\n"; $area2 = "$hStoreCity, $hStoreProv\n"; $inarea{$km}= {area=>$area, area1=>$area1, hStore=>$hStore ... }; } foreach my $km ( sort keys %inarea ) { my $area= $inarea{$km}{area}; my $area1= $inarea{$km}{area1}; ... print " <table border=0 width=240 height=105 cellpadding=15 cellspacing=0 back +ground=\"http://pagelinx.com/herbalmagic/files/loc_bck.gif\"> <tr> <td style=\"font-size: 11px; color: #5D5D5D;\"> Store # <A HREF=\"javascript:change1('pic1','image$count')\">$area</A> +<BR>\n"; print "<div class=\"book\"> <A HREF=\"http://www.pagelinx.com/herbalmagic/form.php?center=$hStoreN +ame&address=$hStoreAdd&city=$hStoreCity&prov=$hStoreProv\" target=_pa +rent>Book Your Free Consultation</a> - KM $km</div></A></td> </tr> </table> \n"; } } }
Re: Sort output
by Anonymous Monk on May 07, 2009 at 00:07 UTC