CGI/Perl Guide | Learning Center | Forums | Advertise | Login
Site Search: in

  Main Index MAIN
INDEX
Search Posts SEARCH
POSTS
Who's Online WHO'S
ONLINE
Log in LOG
IN

Home: Perl Programming Help: Beginner:
Creating alphabetic Sort

 



allan1962
Novice

Jun 3, 2007, 4:29 AM

Post #1 of 24 (5101 views)
Creating alphabetic Sort Can't Post

I have a database with 1 field which I can sort alphabetically, I want to display the database

similar to what I have on this page http://www.peibd.com/categories.html

I am assuming that I can have a script that will read the first letter of each category

While 1st letter is eq A

print $categories

Change A to B

While 1st letter is eq B

print categories

Change B to C

.......etc

Can someone help me with this

Thanks


PGScooter
stranger

Jun 3, 2007, 6:05 AM

Post #2 of 24 (5098 views)
Re: [allan1962] Creating alphabetic Sort [In reply to] Can't Post

Hey Allan, yeah that will work!
Keep going!
If you need help, ask a specific question. For example, "how can I find out what the first letter of a string is?"
It seems to me you've got the logic worked out.
The more you teach me, the more I learn. The more I learn, the more I teach.


miller
User

Jun 3, 2007, 10:16 AM

Post #3 of 24 (5095 views)
Re: [allan1962] Creating alphabetic Sort [In reply to] Can't Post

All databases that I know of will let you sort when making a query. Look up the syntax to ORDER BY as that is the SQL convention.

Also, perl lets you sort an array as well using the sort function.
http://perldoc.perl.org/functions/sort.html

- Miller


PGScooter
stranger

Jun 3, 2007, 12:21 PM

Post #4 of 24 (5090 views)
Re: [miller] Creating alphabetic Sort [In reply to] Can't Post

but would that work considering the main goal is to make categories (unless we knew that there were the same amount of each letter in which case we could store 1-10 in the sorted array under a)? My initial thought would be that it would be best to do a regex to get the first letter and then put that in an array with all the others with that letter.
The more you teach me, the more I learn. The more I learn, the more I teach.


miller
User

Jun 3, 2007, 1:11 PM

Post #5 of 24 (5089 views)
Re: [PGScooter] Creating alphabetic Sort [In reply to] Can't Post

Sorting is ultimately what he wants, as that is even what the example website does.

The fact that they are displayed grouped by first letter is a totally different issue. Once the elements are sorted, grouping by first letter becomes trivial. Not that it's hard to begin with. Even without sorting, it would simply be a matter of using substr, and inputting the data into a hash where the keys were the first letter. QED.

- M


PGScooter
stranger

Jun 3, 2007, 2:24 PM

Post #6 of 24 (5087 views)
Re: [miller] Creating alphabetic Sort [In reply to] Can't Post

ah I didn't even realize that they were sorted within the letter. Yeah I guess it would be best to sort them all at once at the beginning. QED :)
The more you teach me, the more I learn. The more I learn, the more I teach.


allan1962
Novice

Jun 4, 2007, 7:20 AM

Post #7 of 24 (5075 views)
Re: [miller] Creating alphabetic Sort [In reply to] Can't Post


In Reply To
Sorting is ultimately what he wants - No, I've got the sorting done, as that is even what the example website does.

The fact that they are displayed grouped by first letter is a totally different issue. Once the elements are sorted, grouping by first letter becomes trivial. Not that it's hard to begin with. Even without sorting, it would simply be a matter of using substr, and inputting the data into a hash where the keys were the first letter. QED.

- M



However, this is the part I am having the trouble with, grouping by first letter, the sort part has beendone with the existing code that I have. See http://www.peibd.com/cgi-bin/testdata/data.cgi for the sorted list.

I need to display this as seen on http://www.peibd.com/categories.html so what iI am lacking is the skill to code using substr, and inputting the data into a hash where the keys were the first letter.

Hope this explains it a little more cleary

Thanks

Allan


(This post was edited by allan1962 on Jun 4, 2007, 7:24 AM)


allan1962
Novice

Jun 4, 2007, 7:48 AM

Post #8 of 24 (5070 views)
Re: [allan1962] Creating alphabetic Sort [In reply to] Can't Post

I may be pushing my luck here, but I am assuming that I'll need to compare the first letter against an array

@letters = ('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', );
}

That way if no match between the first letter and the array is found I can still display the letter with no entries below it. Like the bottom of the current categories page displays the results

X


Y
Yarns and Sewing Supplies

Z



Thanks Again


allan1962
Novice

Jun 4, 2007, 9:38 AM

Post #9 of 24 (5064 views)
Re: [allan1962] Creating alphabetic Sort [In reply to] Can't Post

Ok This is what I have so far

*********************************************************

open(DATABASE, "datafiles/data.txt") || die "Can't open input";
$count=0;
@data=<DATABASE>;
close (DATABASE);

foreach $data(@data)
{

($Category) = split(/\|/, $data);
push @db_searchresults, $data;
}

foreach $data1(@db_searchresults)
{

chop ($data1);
($Category) = split(/\|/, $data1);
push @db_Category, $Category;

$count++;
$urllink="";
$nextletter=0;

@letters = ('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', );
}


if("$db_Category[0]" eq ""){ print "<BR><div align=center><b><i>No Entry</b><br></div>";
}

$start = "$in{'start'}";

$letters[$nextletter];
while ($count) {
$listing[$i] = substr("$db_Category[$i]",0,1);

if("$letters[$nextletter]" eq "$listing[$i]")
{ $urllink[$i] = "<a href='../listing/display.cgi?search=1&searchtype=all&searchtext=$db_Category[$i]'>$db_Category[$i]</a>";
print qq!
<TR valign="top">
<TD class="category">
$urllink[$i],
</td></TR>
!;
}
else {
$nextletter++;
}
$i++;
--$count;
}
**************************************************************************

Results at http://www.peibd.com/cgi-bin/testdata/data2.cgi

I'm getting close, but still missing something in the comparing the first letter.

As you can see, and an earlier post hinted at, I am trying to make an effort here.

Can someone help me with the final steps?


(This post was edited by allan1962 on Jun 4, 2007, 10:11 AM)


KevinR
Veteran


Jun 4, 2007, 10:41 AM

Post #10 of 24 (5056 views)
Re: [allan1962] Creating alphabetic Sort [In reply to] Can't Post

Your database is really a text file? Can you show a few lines of the database file?
-------------------------------------------------


allan1962
Novice

Jun 4, 2007, 3:28 PM

Post #11 of 24 (5051 views)
Re: [KevinR] Creating alphabetic Sort [In reply to] Can't Post

Hi Kevin,

Here it is;

Accommodations|
Accountants|
Acupuncture Services|
Advertising Services|
Agricultural Services|
Air Conditioning Services|
Aircraft Charter|
Aircraft Service|
Alarm Systems|
Alternator Repair|
Amusement|
Art Galleries|
Arts and Crafts|
Auctioneers|
Automotive Repairs|
Automotive Supplies |
Bag Manufacturing|
Bakery|
Banking/Financial|



Thanks

Allan


allan1962
Novice

Jun 4, 2007, 4:30 PM

Post #12 of 24 (5048 views)
Re: [allan1962] Creating alphabetic Sort [In reply to] Can't Post

OK, I've got it, took a little bit of playing around but here is what I have.

http://www.peibd.com/cgi-bin/testdata/data3.cgi

#!/usr/bin/perl

################################################################
read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
# Split the name-value pairs
@pairs = split(/&/, $buffer);
foreach $pair (@pairs) {
local($name, $value) = split(/=/, $pair);
$value =~ tr/+/ /;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
# strip off any possible SSI comment tags.
$value =~ s/<!--(.|\n)*-->//g;
$in{$name} = $value;
}
print "Content-type: text/html\n\n";

print <<TOPOFPAGE;
<html>
<head>
<title>Demo Data</title>
</head>
<link rel=StyleSheet href="http://www.peibd.com/style.css" type="text/css" media="screen">
<body topmargin="0" leftmargin="0" rightmargin="0" bottommargin="0" marginheight="0" marginwidth="0">
<table width="90%" height="90%" align="center" cellspacing="0" cellpadding="0" border="0"><TR valign="top">
<TD class="category"><br>
A
</td></TR><TR valign="top"><TD class="category">

TOPOFPAGE
#######
open(DATABASE, "datafiles/data.txt") || die "Can't open input";
$count=0;
@data=<DATABASE>;
close (DATABASE);

foreach $data(@data)
{

($Category) = split(/\|/, $data);
push @db_searchresults, $data;
}

foreach $data1(@db_searchresults)
{

chop ($data1);
($Category) = split(/\|/, $data1);
push @db_Category, $Category;

$count++;
$urllink="";
$nextletter=0;

@letters = ('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', );
}


if("$db_Category[0]" eq ""){ print "<BR><div align=center><b><i>No Entry</b><br></div>";
}

$start = "$in{'start'}";
while ($count) {
$listing[$i] = substr("$db_Category[$i]",0,1);
$letters[$nextletter];

$urllink[$i] = "<a href='../listing/display.cgi?search=1&searchtype=all&searchtext=$db_Category[$i]'>$db_Category[$i]</a>,";

if ("$letters[$nextletter]" eq "$listing[$i]")

{
print qq!
$urllink[$i]
!;
$i++;
--$count;
}
else {
print qq!
</td></TR><TR valign="top">
<TD class="category"><br>
$letters[$nextletter+1]
</td></TR><TR valign="top">
<TD class="category">
!;
$i++;
$nextletter++;
--$count;
}
}

print "</td></TR></table>";

print <<EOF;

</body>
</html>

EOF
#end

##############################################

Now that havnig been said, can someone help me put this in 3 columns


(This post was edited by allan1962 on Jun 4, 2007, 6:32 PM)


KevinR
Veteran


Jun 4, 2007, 6:38 PM

Post #13 of 24 (5041 views)
Re: [allan1962] Creating alphabetic Sort [In reply to] Can't Post

Your code works, which is good, but it is poorly coded. It could be simplified and made more efficient. But why does the data file have a "|" on the end of each line? Can that be removed?
-------------------------------------------------


allan1962
Novice

Jun 5, 2007, 2:58 AM

Post #14 of 24 (5037 views)
Re: [KevinR] Creating alphabetic Sort [In reply to] Can't Post

The "|" on the end of the line is there because the script was being used on a multi-field database.

I just wasn't sure how to get rid of it without messing things up further.

I have no doubt that my coding looks awful, but like you say, it works.

With the exception of;

the "A" at the top of the page is hard coded

the "Y" and "Z" fields, because there are no categories for these, aren't displayed

ideally i need the results displayed in 3 columns ( similiar to what's here )

I have used 3 columns to display results with other scripts, but like you say, the code is a mess and I'd likely

bang my head for another 2 days trying to incorporate this.

$rowcount = "$in{'rowcount'}";
$rows = 3;


for ($rc=$rowcount; (($rc < $rowcount+3) && ($rc < $rows));)
{


print record

$rc += 1;

$i += 1;

}

$rows++;

If anyone can help with this it would be appreciated.


(This post was edited by allan1962 on Jun 5, 2007, 3:02 AM)


KevinR
Veteran


Jun 5, 2007, 9:10 AM

Post #15 of 24 (5024 views)
Re: [allan1962] Creating alphabetic Sort [In reply to] Can't Post

I'll see what I can do later today. Right now I am off to work so check back later today.
-------------------------------------------------


allan1962
Novice

Jun 6, 2007, 4:27 PM

Post #16 of 24 (5018 views)
Re: [KevinR] Creating alphabetic Sort [In reply to] Can't Post

Have you had a chance to look at this any further?


(This post was edited by allan1962 on Jun 6, 2007, 4:28 PM)


KevinR
Veteran


Jun 6, 2007, 5:07 PM

Post #17 of 24 (5016 views)
Re: [allan1962] Creating alphabetic Sort [In reply to] Can't Post

I haven't. My son was in an accident and is in the hospital. When things settle down over the next few days if there is no reply I will take a look again.
-------------------------------------------------


KevinR
Veteran


Jun 8, 2007, 11:51 PM

Post #18 of 24 (5002 views)
Re: [allan1962] Creating alphabetic Sort [In reply to] Can't Post

This code could probably be shortened up a bit, but should do what you want.


Code
################################################################ 
read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
# Split the name-value pairs
my @pairs = split(/&/, $buffer);
foreach my $pair (@pairs) {
my($name, $value) = split(/=/, $pair);
$value =~ tr/+/ /;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
# strip off any possible SSI comment tags.
$value =~ s/<!--(.|\n)*-->//g;
$in{$name} = $value;
}

print "Content-type: text/html\n\n";


#######
open(DATABASE, "datafiles/data.txt") || die "Can't open input";
my @data = <DATABASE>;
chomp @data;
close (DATABASE);

my $link = '<a href="../listing/display.cgi?search=1&searchtype=all&searchtext=';
my @letters = ('A'..'Z');
my %cats = ();

foreach my $subcats (@data) {
push @{ $cats{substr $subcats,0,1} },$subcats;
}

print qq~
<html>
<head>
<title>Demo Data</title>
</head>
<link rel=StyleSheet href="http://www.peibd.com/style.css" type="text/css" media="screen">
<body topmargin="0" leftmargin="0" rightmargin="0" bottommargin="0" marginheight="0" marginwidth="0">
<table width="90%" height="90%" align="center" cellspacing="0" cellpadding="0" border="0">
~;

foreach my $subcats (@letters) {
print qq~<tr><td class="category" colspan="3"><b>$subcats</b></td></tr>\n~;
if (! exists $cats{$subcats}) {
print qq~<tr><td class="category" colspan="3">No Entry</td></tr>\n~;
print qq~<tr><td class="category" colspan="3">&nbsp;</td></tr>\n~;
next;
}
my $r = scalar @{$cats{$subcats}}%3;
my $n = (scalar @{$cats{$subcats}}-$r) / 3;
if ($r == 0){
print q~<tr valign="top"><td class="category">~;
print qq~$link$_">$_</a><br>\n~ for @{$cats{$subcats}}[0 .. $n-1];
print q~</td><td class="category">~;
print qq~$link$_">$_</a><br>\n~ for @{$cats{$subcats}}[$n .. $n+$n-1];
print q~</td><td class="category">~;
print qq~$link$_">$_</a><br>\n~ for @{$cats{$subcats}}[$n+$n .. $#{$cats{$subcats}}];
print qq~</td></tr>\n~;
}
elsif ($r == 1){
print q~<tr valign="top"><td class="category">~;
print qq~$link$_">$_</a><br>\n~ for @{$cats{$subcats}}[0 .. $n];
print q~</td><td class="category">~;
print qq~$link$_">$_</a><br>\n~ for @{$cats{$subcats}}[$n+1 .. $n+$n];
print q~</td><td class="category">~;
print qq~$link$_">$_</a><br>\n~ for @{$cats{$subcats}}[$n+$n+1 .. $#{$cats{$subcats}}];
print qq~</td></tr>\n~;
}
else {
print q~<tr valign="top"><td class="category">~;
print qq~$link$_">$_</a><br>\n~ for @{$cats{$subcats}}[0 .. $n];
print q~</td><td class="category">~;
print qq~$link$_">$_</a><br>\n~ for @{$cats{$subcats}}[$n+1 .. $n+$n+1];
print q~</td><td class="category">~;
print qq~$link$_">$_</a><br>\n~ for @{$cats{$subcats}}[$n+$n+2 .. $#{$cats{$subcats}}];
print qq~</td></tr>\n~;
}
print qq~<tr><td class="category" colspan="3">&nbsp;</td></tr>\n~;
}
print q~</table>
</body>
</html>~;

-------------------------------------------------


allan1962
Novice

Jun 9, 2007, 7:11 AM

Post #19 of 24 (4999 views)
Re: [KevinR] Creating alphabetic Sort [In reply to] Can't Post

Hi Kevin,

How's your son?

The script works great!, with one exception. The " | " needs to be stripped off the results at the end of each record.

The pipe is inserted when the entry is made into the database, it is used throughout the database manager

for sorting records, adding deleting etc.

That's why I had the push to a new array at the start of my code, I could try and incorporate what I had with your code, but I have a sneaky suspicion that I could mess it up. Is it possible for you to look at this?

Thanks

Allan


KevinR
Veteran


Jun 9, 2007, 11:47 AM

Post #20 of 24 (4997 views)
Re: [allan1962] Creating alphabetic Sort [In reply to] Can't Post

to remove the pipe try adding the line in bold below to the existing script and see how it works:


Code
foreach my $subcats (@data) {  
$subcats =~ s/\|$//d;
push @{ $cats{substr $subcats,0,1} },$subcats;
}


My son is doing OK thanks.
-------------------------------------------------


allan1962
Novice

Jun 9, 2007, 12:29 PM

Post #21 of 24 (4994 views)
Re: [KevinR] Creating alphabetic Sort [In reply to] Can't Post

Tried this and get an error.


KevinR
Veteran


Jun 9, 2007, 12:33 PM

Post #22 of 24 (4992 views)
Re: [allan1962] Creating alphabetic Sort [In reply to] Can't Post

oops, should be:


Code
$subcats =~ s/\|$//;


remove the "d" at the end of the regexp
-------------------------------------------------


allan1962
Novice

Jun 9, 2007, 12:38 PM

Post #23 of 24 (4991 views)
Re: [allan1962] Creating alphabetic Sort [In reply to] Can't Post

I tried this and it worked.

foreach $data(@data)
{

($subcats) = split(/\|/, $data);
push @db_searchresults, $data;
}

foreach $data1(@db_searchresults)
{

chop ($data1);
($subcats) = split(/\|/, $data1);
push @{ $cats{substr $subcats,0,1} },$subcats;
}

_____________________________________

Thanks for everything Kevin, this is greatly appreciated.

Allan


(This post was edited by allan1962 on Jun 9, 2007, 12:38 PM)


KevinR
Veteran


Jun 9, 2007, 12:47 PM

Post #24 of 24 (4988 views)
Re: [allan1962] Creating alphabetic Sort [In reply to] Can't Post

Use the corrected regexp, it should be much more efficient than what you are doing.
-------------------------------------------------

 
 


Search for (options) Powered by Gossamer Forum v.1.2.0

Web Applications & Managed Hosting Powered by Gossamer Threads
Visit our Mailing List Archives