Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic
 
PerlMonks  

Sorting by Date Help!

by Anonymous Monk
on Mar 17, 2009 at 18:12 UTC ( [id://751248]=perlquestion: print w/replies, xml ) Need Help??

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

Hi Monks!

I am trying to search by date here on this:
@stuff = ( {"submitted","01/22/08"}, {"submitted","01/12/08"}, {"submitted","04/01/09"}, {"submitted","10/04/08"}, {"submitted","01/10/09"}, {"submitted","12/12/09"}, {"submitted","01/22/09"}, {"submitted","01/12/09"}, {"submitted","12/30/08"}, {"submitted","12/22/08"}, {"submitted","12/15/08"}, {"submitted","01/05/09"}, {"submitted","01/19/09"}, {"submitted","01/21/09"} ); @newstuff = sort bydte @stuff; foreach $pers (@newstuff) { print $$pers{submitted}."\n"; } sub bydte { $$a{submitted} <=> $$b{submitted}; #$$a{submitted} cmp $$b{submitted}; }

And my goal is to get all the most recent dates on top, I tried and no luck. Any help?
Thanks for the Help!

Replies are listed 'Best First'.
Re: Sorting by Date Help!
by moritz (Cardinal) on Mar 17, 2009 at 18:34 UTC
    $$a{submitted} <=> $$b{submitted};

    <=> does numeric comparison, so your code will only compare by the first number in the string. Transform your data into a format like 08-02-28, then you can use simple string comparison to get correct date comparison.

      Still did not work, but another question to try to simplify what I am asking is if a had a Array of Hashes, like:

      my @data; push @data, {name => "Submitted", date => 01/03/08 }; push @data, { name => "Submitted", date => 04/04/09 }; push @data, { name => "Submitted", date => 12/01/08}; push @data, { name => "Submitted", date => 12/01/09}; push @data, { name => "Submitted", date => 08/10/08}; my @sorted = sort { $a->{date} <=> $b->{date} } @data;

      Would that sort by the most recent date?
        Still did not work

        In what way? I'm surprised... show us what code you've tried, so that we can tell you what's wrong and how to fix it.

        push @data, {name => "Submitted", date => 01/03/08 };

        If you write 01/03/08 it will complain with Illegal octal digit '8' at.

        Would that sort by the most recent date?

        No, because you still haven't fixed the comparison semantics.

Re: Sorting by Date Help!
by almut (Canon) on Mar 17, 2009 at 19:54 UTC
    my @stuff = ( {submitted => "01/22/08"}, {submitted => "01/12/08"}, {submitted => "04/01/09"}, {submitted => "10/04/08"}, {submitted => "01/10/09"}, {submitted => "12/12/09"}, {submitted => "01/22/09"}, {submitted => "01/12/09"}, {submitted => "12/30/08"}, {submitted => "12/22/08"}, {submitted => "12/15/08"}, {submitted => "01/05/09"}, {submitted => "01/19/09"}, {submitted => "01/21/09"} ); my @sorted = map { $_->[0] } sort { $b->[1] cmp $a->[1] } # map { print "$_->[1]\n"; $_ } # uncomment for debugging purposes map { [$_, join('', (split(/\//, $_->{submitted}))[2,0,1] )] } @stuff; foreach my $res (@sorted) { print $res->{submitted}."\n"; }

    See Schwartzian Transform

      It worked, if you would have to explain this code to someone, would the "Schwartzian Transform" link be the place to start? Thanks for the help!
        would the "Schwartzian Transform" link be the place to start?

        Yes, I think so, as from there you'll also find a link to the original Unix Review column. The latter explains it in detail, but the PerlMonks thread provides additional discussion...

        What isn't explained there is the specific implementation of the "expensive_func" being used here.  So just in case :)

        join('', (split(/\//, $_->{submitted}))[2,0,1] )

        This splits the date strings by "/", rearranges the three parts so that year comes first, then month, then day (which makes the dates easily sortable by string comparison), and joins them into a single string like "080122" (for 01/22/08).  The (...)[2,0,1] construct is described in perldata (search for "list slice").

Re: Sorting by Date Help!
by poolpi (Hermit) on Mar 17, 2009 at 22:11 UTC
    use strict; use warnings; use DateTime; my @sorted_dates = sort { DateTime->compare_ignore_floating($$b{'submitted'}, $$a{'submitted'}) } map { my ( $month, $day, $year ) = ( split( '/', $_ ) )[ 0 .. 2 ]; { qq(submitted), DateTime->new( year => $year + 2000, month => $month, day => $day, time_zone => 'Europe/Paris', ) } } qw{ 01/22/08 01/12/08 04/01/09 10/04/08 01/10/09 12/12/09 01/22/0 +9 01/12/09 12/30/08 12/22/08 12/15/08 01/05/09 01/19/09 01/21/09}; print $sorted_dates[$_]{'submitted'}->mdy('/'), "\n" for 0 .. $#sorted_dates; __END__ Output: 12/12/2009 04/01/2009 01/22/2009 01/21/2009 01/19/2009 01/12/2009 01/10/2009 01/05/2009 12/30/2008 12/22/2008 12/15/2008 10/04/2008 01/22/2008 01/12/2008


    hth,
    PooLpi

    'Ebry haffa hoe hab im tik a bush'. Jamaican proverb
Re: Sorting by Date Help!
by VinsWorldcom (Prior) on Mar 17, 2009 at 19:55 UTC

    I may be misunderstanding how you want it sorted, but if you keep the date format you have, you won't be able to sort how you (I think) want.

    12-01-08 01-01-07 12-01-06 01-01-98

    will sort:

    01-01-07 01-01-98 12-01-06 12-01-08

    It will sort all the January's first, then all the Februarys, etc... Result will be that January 1998, comes before December 2008, which is not what you want - I'm guessing. If you reverse order, you'd get all the December's first which would make December 2006 come before January 2007. Still not correct.

    Have you tried using a different date format - or using Perl to convert the dates you have to a sortable format and then printing them back the way you want?

    IMHO, the best way to sort dates would be: YYYYMMDD.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://751248]
Approved by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others taking refuge in the Monastery: (5)
As of 2024-04-26 08:37 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found