develooper Front page | perl.macosx | Postings from March 2005

Re: Sorting year and month

Thread Previous | Thread Next
From:
Sherm Pendley
Date:
March 1, 2005 00:59
Subject:
Re: Sorting year and month
Message ID:
6b0150ba12bb5c91da5aaeb8fc0e4827@dot-app.org
On Mar 1, 2005, at 2:48 AM, Mark Wheeler wrote:

> Hi Sherm,
>
> That works perfectly. Could you give me a brief rundown on how the 
> sort works with Date::Manip, so I can understand what is going on?
>
> On Feb 28, 2005, at 1:03 AM, Sherm Pendley wrote:
>
>     my @sorted = sort { Date_Cmp(ParseDate($b), ParseDate($a)); } 
> @dates;

I'm not certain how much detail you need, so I'll start at the 
beginning, with sort(). Sort() allows you to provide a block of code 
that's used as a comparison function. Two arguments are passed to that 
function - $a and $b - and the return value should mimic that of <=> or 
cmp - that is, < 0 if $a < $b, 0 if $a == $b, and > 0 if $a > $b.

So, suppose we have a list of hashes, like this:

     my @garbled = (
         { 'foo'=>'trouble', 'sort_by'=>3 },
         { 'foo'=>'hubble', 'sort_by'=>0 },
         { 'foo'=>'toil', 'sort_by'=>2 },
         { 'foo'=>'bubble', 'sort_by'=>1 },
     );

We could sort it according to the "sort_by" field like this:

     my @spell = sort { $a->{'sort_by'} <=> $b->{'sort_by'} } @garbled;

Note that there's no comma between the comparison function and 
@garbled. If there were, Perl would treat the block as the first 
element in the list to be sorted. Also, $a and $b are magic - you don't 
have to declare them with my() or our(), or shift them off of @_. 
They're just there. Also, strict knows about them, although not in 
detail; you can use an undeclared $a or $b *anywhere*, not just with a 
sort(), without hearing a peep from strict.

So anyway, how's that work with Date::Manip?

The ParseDate() function takes a date in a variety of formats, and 
returns it in a normalized format: "yyyymmddhh:mm:ss". Date_Cmp() 
compares two of these normalized date strings, and returns a value 
that's consistent with <=> or cmp - that is, <0, 0, or >0 - as expected 
by sort.

You *could* simply use cmp to compare these strings - in fact that's 
basically all Date_Cmp() does right now - but the Date::Manip docs 
indicate that the normalized format will be extended at some future 
point, to include various flags such as the time zone. At that point, 
Date_Cmp() will also be updated to take the flags into account, whereas 
cmp will no longer work. So, using Date_Cmp() is optional at the 
moment, but it's more future-proof than cmp.

sherm--

Cocoa programming in Perl: http://camelbones.sourceforge.net
Hire me! My resume: http://www.dot-app.org


Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About