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: Intermediate:
sort help

 



spaz
Novice

Jul 16, 2001, 8:44 AM

Post #1 of 4 (708 views)
sort help Can't Post

I have a list of news article information in a database for a year. There are dates in one of the fields and I need to organize them by month and then by date on the return page -- most recent to oldest within the year. I haven't been able to get them to sort by date. I can get them by the month, with a header telling what month it is. Here's the code I'm using. The dates are full, such as July 16, 2001, so I would think the sort function is sort {$a cmp $b}.
Also:
$FORM{'y'} = 2001

Sample db - opened and labeled @Data
1|bd|Article 1|xxx5|March 15, 2001|Article about site|article link
2|bd|Article 2|futon.com|March 1, 2001|Article about beds|article link
3|bd|Article 3|Test|March 20, 2001|Article about nothing|article link
4|bd|Article 4|test2|February 10, 2001|Article about nothing again|article link

**********************
print "<table cellpadding=\"0\" cellspacing=\"0\" border=\"0\" width=\"100%\">\n";
@months =("January","February","March","April","May","June","July","August","September","October","November","December");
@months = reverse(@months);

foreach $month (@months)
{

foreach $Story (@Data)
{
@Temp = split (/\|/, $Story);

if ($Temp[4] =~ /$FORM{'y'}/)
{
if ($Temp[4] =~ /$month/)
{

#print month header once
if ($x < 1)
{
print qq~
<P><FONT FACE="helvetica, arial" SIZE="3" COLOR="#006633">
<b>$month $FORM{'y'}</b></font>
<HR SIZE="1" NOSHADE>
<FONT SIZE="2" FACE="helvetica, arial, sans-serif" class="bodyText">~;
$x = 1;
}

#display articles, starting with most recent
print qq~
<B>"$Temp[2]"</B><BR>
<i>$Temp[3]</I>, $Temp[4]<BR>
$Temp[5]

~;
}

}
}

$x = 0; #reset month header
}

print "</table>\n";



abstracts
Novice

Jul 16, 2001, 2:22 PM

Post #2 of 4 (699 views)
Re: sort help [In reply to] Can't Post

Hello,
You have data that you want to sort, but the sorting is not as straightforward as <=> or cmp. The function cmp will not work because the sequence of dates will be something line 1, 11, 12, 13, ..., 19, 2, 21, 22, ..., 29, 3, 30, 31, 4, 5, ..., 9 which is wrong. Also, the names of the months are not sorted alphabetically, at least not in english. So, the time format needs to change to something like "YYYYMMDD" and that number can be sorted numerically. That step should be done after splitting the fields of course.

So, let's step through a solution.

Code
# open the file as usual, here we open DATA 
my @data;
for(<DATA>){
my @fields = split/\|/; # here we get 7 fields from the db
my($mon, $day, $year) = split(/\s+/, $fields[4]);
$fields[7] = sprintf("&#037;04d&#037;02d&#037;02d", $year, $mon{$mon}, $day);
push @data, \@fields; # push a reference to this raw to the list
}
my @sorted = sort{$b->[7] <=> $a->[7]} @data; #sort by the date we made
for(@sorted){
my @fields = @$_;
print join("|", @fields[0..6]);
}

OR, just do all in one step using the Schwartzian Transform:

Code
print 
map { join("|", @$_[0..6])}
sort {$b->[7] <=> $a->[7]}
map {
my @fields = split /\|/;
($fields[7] = $fields[4])
=~ s[(\S+)\s+(\S+),\s+(\S+)]
[sprintf("&#037;04d&#037;02d&#037;02d", $3, $mon{$1},$2)]e;
\@fields;
} <DATA>;

Hope this helps,,,

Aziz,,,



abstracts
Novice

Jul 16, 2001, 2:34 PM

Post #3 of 4 (696 views)
Re: sort help [In reply to] Can't Post

Of corse this line needs to be added

Code
my %mon; 
@mon{qw/January February March April May June July August September October
November December/} = 1..12;



spaz
Novice

Jul 17, 2001, 8:05 AM

Post #4 of 4 (687 views)
Re: sort help [In reply to] Can't Post

I'm still not getting it to work. I made a change to the db script to convert the date to yyyymmdd and add it to the database. The new db file is:
1|bd|Article 1|Smartmony.com|March 15, 2001|Article about Enterprise|article link|20010315
2|bd|Article 2|Enterprise|March 1, 2001|Article about Enterprise|article link|20010301
3|bd|Article 3|Test|March 20, 2001|Article about Enterprise|article link|20010320
4|bd|Article 4|Smartmony.com|February 10, 2001|Article about Enterprise|article link|20010210
5|bd|Test with new date|ent|February 28, 2001|No description|link|20010228

I'm still not getting the sort portion right, although I'm trying to sort by the new field.

print "<table cellpadding=\"0\" cellspacing=\"0\" border=\"0\" width=\"100%\">\n";
@months =("January","February","March","April","May","June","July","August","September","October","November","December");
@months = reverse(@months);
foreach $month (@months)
{

foreach $Story (@Data)
{

@Temp = split (/\|/, $Story);

@numbers = $Temp[7];

foreach $article (sort {$b <=> $a} @numbers)
{

if ($Temp[4] =~ /$FORM{'y'}/)
{
if ($Temp[4] =~ /$month/)
{

#print month header once
if ($x < 1)
{
print qq~
<P><FONT FACE="helvetica, arial" SIZE="3" COLOR="#006633">
<b>$month $FORM{'y'}</b></font>
<HR SIZE="1" NOSHADE>
<FONT SIZE="2" FACE="helvetica, arial, sans-serif" class="bodyText">~;
$x = 1;
}

#print article information
print qq~
<B>"$Temp[2]"</B><BR>
<i>$Temp[3]</I>, $Temp[4]<BR>
$Temp[5]~;
if ($Temp[6] ne "")
{
print " <a href=\"$Temp[6]\">Read</a> the article.

\n";
}
else {
print "

\n";
}

}

}
}
}

$x = 0;
}
print "</table>\n";


DO I HAVE THE SORT FUNCTION IN THE WRONG PLACE? ~spaz



 
 


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

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