Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister

Sorting by date

by Anonymous Monk
on Jan 06, 2004 at 00:33 UTC ( #318983=perlquestion: print w/replies, xml ) Need Help??
Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

I'm trying to print a table sorted by the date. The date format I'm using is #.#.## or #.##.##. For example $date = "1.13.04";.

How can I get these to print in reverse order by date so the newest date is on top? It may be confusing, but I have a whole mess of records in my SDBM that are dated, I need to bring them back out in a new order.

The tricker part would be after seperating by date, how can I make it prints a new table for each month? For example:

foreach (reverse sort keys %list) { <table> <tr><td>1.1.04</td><td>first record</td></tr> <tr><td>1.21.04</td><td>next record, same month</td></tr> </table> <table> <tr><td>2.13.04</td><td>New table becuse it's a new month</td></tr> </table> }
Any help would be very much appreciated.

Replies are listed 'Best First'.
Re: Sorting by date
by Roger (Parson) on Jan 06, 2004 at 01:02 UTC
    use strict; use Data::Dumper; my @date = qw/ 1.13.04 1.12.04 3.13.04 /; my @sorted_date = map { $_->[0] } # retrieve the original date sort { $b->[1] <=> $a->[1] } # sort the normalized date map { my @n = /(\d+)\.(\d+)\.(\d+)/; # normalize the date my $d = sprintf "%02d%02d%02d", @n[2,0,1]; [$_, $d] } @date; print Dumper(\@sorted_date);
    and the output:
    $VAR1 = [ '3.13.04', '1.13.04', '1.12.04' ];
      The only problem with this is, I'm not working with arrays. I have my list setup like: name => date:message:email.

      So to begin with, I need to

      foreach (keys %list) { my $value = $list{$_}; my ($date, $message, $email) = split(/:/, $value); print "The date is: $date"; # 1.11.04 or 8.3.04 }
      Since I'm not working with arrays, I don't think I can map and compare unless I'm confused as to what I'm doing. But IF I can get it to print by date, how do I get it to print a new table for each month?

      Thanks for your help.

        use strict; use Data::Dumper; my %list = ( A => '1.13.04:Record:A', B => '1.12.04:Record:B', C => '3.13.04:Record:C', ); my @sorted_date = map { $_->[0] } sort { $b->[1] <=> $a->[1] } map { my @n = /^(\d+)\.(\d+)\.(\d+):/; my $d = sprintf "%02d%02d%02d", @n[2,0,1]; [join('.',@n), $d] } values %list; print Dumper(\@sorted_date);

        OK, here's another variant of the sort that produces the HTML table as required...
        use strict; use Data::Dumper; my %list = ( A => '1.13.04:Record:A', B => '1.12.04:Record:B', C => '3.13.04:Record:C', D => '3.13.02:Record:D', ); my @sorted_date = map { [ $_->[1], $_->[0], $_->[2] ] } sort { $b->[1] <=> $a->[1] } map { my @n = $list{$_} =~ /^(\d+)\.(\d+)\.(\d+):/; my $d = sprintf "%02d%02d%02d", @n[2,0,1]; [join('.',@n), $d, $_] } keys %list; my $month; foreach (@sorted_date) { my $m = substr($_->[0], 0, 4); # retrieve YYMM if ($month ne $m) { print "</table>\n" if $month; $month = $m; print "<table>\n"; } print "<tr><td>$_->[1]</td><td>HASH key: $_->[2]</td></tr>\n"; } print "</table>\n" if $#sorted_date >= 0;

        And the output is:
        <table> <tr><td>3.13.04</td><td>HASH key: C</td></tr> </table> <table> <tr><td>1.13.04</td><td>HASH key: A</td></tr> <tr><td>1.12.04</td><td>HASH key: B</td></tr> </table> <table> <tr><td>3.13.02</td><td>HASH key: D</td></tr> </table>
Re: Sorting by date
by runrig (Abbot) on Jan 06, 2004 at 00:54 UTC
Re: Sorting by date
by pzbagel (Chaplain) on Jan 06, 2004 at 00:54 UTC

    I would suggest using if you want to do this with modules. It is very helpful when it comes to figuring out which month/week of the year a given date falls in.

    Otherwise, when I want to avoid using a module and I am dealing with simple things like sorting based on date, I convert the date to the YYYYMMDD format. Now the dates can be sorted numerically very quickly.


      Just make sure that YYYY is in 4-digit format and MM or DD in 2-digit format.

      Like in this case: 20040113 (for 2003, Jan. 13) may mean numerically different from 2004113 (this might mean 2004, Jan. 13 or 2004, Nov. 3)

      Had you been using a database like MySQL, that shouldn't have been an issue.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://318983]
Approved by Roger
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others imbibing at the Monastery: (6)
As of 2017-08-17 18:33 GMT
Find Nodes?
    Voting Booth?
    Who is your favorite scientist and why?

    Results (290 votes). Check out past polls.