Fellow monks:
First of all, the code here actually works. But can it be done better? (You might want to skip this node unless you're a golfer or efficiency nut).
Desc: each database record contains a name with their city and state. There can be multiple records with the same state and city; e.g., 10 in Texas with 5 in Dallas, 2 in Fort Worth, 3 in Waco, etc. At this point in the script, I only want to show each unique state with unique city names underneath; e.g., 1 heading for Texas, with 1 listing each for Dallas, Fort Worth, and Waco under it. You know the drill.
Like I said, it works. But code feels amateurish, like using the $temp_ variables to hold the first instance of a state or city. I've read nodes here on PM using
grep and
map to normalize arrays, and checked the Perlfaqs, but not sure how those methods would work with the hash or would be any cleaner. Comments? Ideas? Tee-time? Thanks.
while (@data = $sth->fetchrow_array()) {
if ($data[1] ne $tempstate) {
undef (@cities);
push (@cities, $data[0]);
$states{$data[1]} = [ @cities ];
$tempstate = $data[1];
$tempcity = $data[0];
} elsif ($data[0] ne $tempcity) {
push (@cities, $data[0]);
$states{$tempstate} = [ @cities ];
$tempcity = $data[0];
}
}
For the entire script:
#!/usr/bin/perl
print "Content-type: text/html\n\n";
use warnings;
use CGI::Carp qw(fatalsToBrowser);
use strict;
my ($dbh, $sth, $stmt, $tempstate, $tempcity, %states, @data, @cities,
+ $city, $x);
&dbconnect; #connect to database subroutine
$stmt = "SELECT city, state, country FROM sponsor ORDER BY country,
+ state, city";
$sth = $dbh->prepare($stmt) or die "prepare: $stmt: $DBI::errstr";
$sth->execute() or die"execute: $stmt: $DBI::errstr";
while (@data = $sth->fetchrow_array()) {
if ($data[1] ne $tempstate) {
@cities = "";
push (@cities, $data[0]);
$states{$data[1]} = [ @cities ];
$tempstate = $data[1];
$tempcity = $data[0];
} elsif ($data[0] ne $tempcity) {
push (@cities, $data[0]);
$states{$tempstate} = [ @cities ];
$tempcity = $data[0];
}
}
for my $state ( keys %states ) {
print "$state:<br />";
for my $i (1..$#{ $states{$state} } ) {
print "$i = $states{$state}[$i]<br />";
}
}
$sth->finish();
$dbh->disconnect();
—Brad
"A little yeast leavens the whole dough."
Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
Read Where should I post X? if you're not absolutely sure you're posting in the right place.
Please read these before you post! —
Posts may use any of the Perl Monks Approved HTML tags:
- a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
| |
For: |
|
Use: |
| & | | & |
| < | | < |
| > | | > |
| [ | | [ |
| ] | | ] |
Link using PerlMonks shortcuts! What shortcuts can I use for linking?
See Writeup Formatting Tips and other pages linked from there for more info.