Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot

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 surveying the Monastery: (5)
As of 2018-03-24 06:45 GMT
Find Nodes?
    Voting Booth?
    When I think of a mole I think of:

    Results (297 votes). Check out past polls.