Speedfreak has asked for the wisdom of the Perl Monks concerning the following question:

Hej all

Heres an interesting one...

I have a delimited file which contains 3 fields; date, id and title. Now, what I am doing is opening this file, reading in the file and pushing it into an array so I have ($date, $id, $title)

Once I have the array and the file closed, I want to sort the array (if necessary pushing the sort into another array) using the date field with the most recent date as 1 and the oldest as the last.

The date format is "yyyy-mm-dd" and I am only looking at about 100 records or so, so nothing massive.

Can anyone give me some pointers?

- Jed

  • Comment on Sorting an array by dates in a field...

Replies are listed 'Best First'.
Re: Sorting an array by dates in a field...
by voyager (Friar) on Jul 07, 2001 at 03:07 UTC
    You first need to get your data into an array of array refs. Assuming your date in the first elemeent:
    while <FH> { my @$record = split $delimiter, $_; push(@unsorted, $record); } @sorted = sort { $b->[0] cmp $a->[0] } @unsorted;
    Note the order of $a, $b since you wanted oldest first, i.e., descending sort.
Re: Sorting an array by dates in a field...
by Zaxo (Archbishop) on Jul 07, 2001 at 06:25 UTC

    If the date format is followed rigidly, with leading 0 for single digit months and days, then a simple alpha sort will work. Since you want reverse order, I'll show how to get that from the sort routine.

    my @sorted = sort { $b->[0] cmp $a->[0] } @data;

    The $b value is on the left to induce reverse order.

    If the date format is not so rigidly observed, you can either rewrite it internally to conform to the format, or else do the sort the hard way. That uses a numerical comparison of years, if same then months if same then days:

    my @sorted = sort { my @b = split '-', $b->[0]; my @a = split '-', $a->[0]; $b[0] <=> $a[0] || $b[1] <=> $a[1] || $b[2] <=> $a[2]; } @data;

    Hope this helps.

    After Compline,
    Zaxo

      Hello! It's very simple to sort date format array.

      #! /usr/bin/perl -w use strict; use Date::Simple ('date', 'today'); my @dates = ("2010-01-27","2010-01-21","2010-02-13","2010-01-10","2009 +-12-28"); my @ordered = sort{ date($b) <=> date($a)} @dates; #descend order print "@ordered\n";

      This is the result: 2010-02-13 2010-01-27 2010-01-21 2010-01-10 2009-12-28

Re: Sorting an array by dates in a field...
by myocom (Deacon) on Jul 07, 2001 at 02:56 UTC

    I think what you explained is not, in fact, what you have. You describe a file that has three bits of information in it: one date, one id, and one title. You assign this to an array such that element zero is $date, one is $id, and two is $title.

    This is clearly not the case, or there would be no sorting to do! :-) Could you post your code (remember to surround your code with <code> tags) and some sample data?

      O.K, sorry! Its 1:22am here and I'm not thinking straight! %P

      I havent got the data yet so at the moment i'm just "simulating" 3 lines from the file being in the array:

      #!/usr/bin/perl my @data; push @data, [ split (/\|/,"2001-07-07|12345|This is a test 1") ]; push @data, [ split (/\|/,"2001-07-08|23456|This is a test 2") ]; push @data, [ split (/\|/,"2001-07-06|34567|This is a test 3") ]; print $data[0][0];

      So as you can see, at the end it prints "2001-07-07" which is the "first row, first column" of the array.

      What I want to do is that this array and sort it by date in descending order using the date field.

      By the way - what IS the proper term for these sorts of arrays in Perl and how do you refer to the "rows and columns" I always use? *S* I mean, what is it when you know how many "columns" you have but the number of rows (say its being read from a file) is variable?

      - Jed

Re: Sorting an array by dates in a field...
by mr.dunstan (Monk) on Jul 07, 2001 at 04:20 UTC
    I like using dates in the format: YYMMDD ... that way, if you're only dealing with dates after Dec 31, 1999 you can do a nice easy numeric sort on those dates ...

    Hope everyone had a nice 010704!

    -mr.dunstan