Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical
 
PerlMonks  

Hash sorting with dates and 12 hour time format.

by shift9999 (Acolyte)
on Sep 15, 2009 at 20:57 UTC ( [id://795476]=perlquestion: print w/replies, xml ) Need Help??

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

I have been reviewing the perlfaq on using the sort function correctly but so far have not been able to get the exact output I need.

I have a hash setup with the dates and times as the keys and the data as the value. I need to sort the dates and times properly. this would normally not be a big issue but the times are in 12 hour format.

here is the format of the hash:
$line_data{"9/10 @ 12:45 PM"} = "some superfluous data here";
Here is the sort:
foreach $key (sort (keys(%line_data))) { print "$key $line_data{$key}\n"; }
This will sort the dates and times but seems to ignore the AM/PM.

The code above does not reflect it but I have tried expanding on the sort with a custom sub called from it. I have not been sucessfull in setting up the right comparison code. More information to follow as I tinker with the sort helper sub.

Any help would be appreciated.

Replies are listed 'Best First'.
Re: Hash sorting with dates and 12 hour time format.
by Roy Johnson (Monsignor) on Sep 15, 2009 at 21:15 UTC
    You may find it helpful to use Time::Local to turn your data into sortable numbers.

    Caution: Contents may have been coded under pressure.
Re: Hash sorting with dates and 12 hour time format.
by gwadej (Chaplain) on Sep 15, 2009 at 21:09 UTC

    When working on a multi-key sort, it's important to text the items in the right order. In this case, you need to do the comparisons in the following order:

    1. month (9)
    2. day (10)
    3. am/pm (PM)
    4. hour (12)
    5. minute (45)

    In addition, you will need to deal with the fact that 12:01 AM should sort to less than 1:00 AM. Your months also won't sort nicely ('10' sorting to less than '9').

    You could break this string into a series of sub-keys and compare them in order, or pack them up into a fixed-field string that sorts how you want.

    Once you've figured out your key, you'll want to apply either the Schwartzian Transform or the Guttman Rosler Transform to the problem.

    Update: Added links for the algorithms.

    G. Wade
Re: Hash sorting with dates and 12 hour time format.
by ikegami (Patriarch) on Sep 15, 2009 at 21:30 UTC
    my @sorted_keys = map substr($_, 10), sort map sprintf('%02d%02d%5$s%02d%02d', m{(\d+)/(\d+) \@ (\d+):(\d+) (AM|PM)}) . $_ keys(%line_data);

    Update: Oops, I knew my AM/PM handling was wrong. Fixed:

    my @sorted_keys = map substr($_, 10), sort map { my ($m,$d,$H,$M,$ampm) = m{(\d+)/(\d+) \@ (\d+):(\d+) (AM|PM)}; $H %= 12; sprintf('%02d%02d%s%02d%02d%s', $m,$d,$ampm,$H,$M, $_) } keys(%line_data);
Re: Hash sorting with dates and 12 hour time format.
by ramlight (Friar) on Sep 15, 2009 at 21:14 UTC
    If you have control of the hash generation, then you might want consider reformatting the time used for the key to avoid this problem. That is likely to be far easier than trying to come up with some specialized sort functions.

    If, on the other hand, you are stuck with the date format that is presented, you have a harder problem (which I will leave to someone who is more of an expert on sort than I.)

      I can control date/time input to the hash so I will try formatting the date/time after the sort. The reason why this was not done already is that it will break another area of the script. I need to determine what is more beneficial.

      Thanks for your responses, I will try out a few of these ideas when I can.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others wandering the Monastery: (8)
As of 2024-04-16 08:25 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found