I agree with you cog regarding the the ST over the OM but that's probably because I've never used the OM in anger so I'm not familiar with it. I think that both JediWizard's solution and yours overcomplicate the transformation of the date into a sortable form. Just reversing the date to sort it and then reversing it again to extract it seems much simpler and quicker to me. I have done some benchmarking which seems to bear this out. I've also corrected a couple of typos (you had missed a closing quote in one of your hash keys but I've unquoted them all and JediWizard had doubled his quote words like qw(qw( ... )). Here is the code
use strict;
use warnings;
use Benchmark qw(cmpthese);
# Generate a thousand dates at random.
#
my @startDates;
push @startDates,
sprintf(q{%02d}, int((rand 28) + 1))
. q{-}
. sprintf(q{%02d}, int((rand 12) + 1))
. q{-}
. int((rand 25) + 2000)
for (1 .. 1000);
# cog's method.
#
my $rcCog = sub
{
my @sortedDates =
map { $_->{date} }
sort
{
$a->{year} <=> $b->{year} or
$a->{month} <=> $b->{month} or
$a->{day} <=> $b->{day}
}
map
{
/(\d\d)-(\d\d)-(\d\d\d\d)/;
{
date => $_,
day => $1,
month => $2,
year => $3
}
}
@startDates;
return $sortedDates[0];
};
# JediWizard's method.
#
my $rcJediWizard = sub
{
my %dateHash = ();
my @sortedDates =
sort
{
($dateHash{$a} ||= transDate($a))
<=>
($dateHash{$b} ||= transDate($b))
}
@startDates;
return $sortedDates[0];
};
# johngg's method.
#
my $rcJohnGG = sub
{
return
(
map {join q{-}, reverse split /-/}
sort
map {join q{-}, reverse split /-/}
@startDates
)[0];
};
# Run all three on data to prove they come up with
# the same answer.
#
print q{$rcCog->() - }, $rcCog->(), qq{\n};
print q{$rcJediWizard->() - }, $rcJediWizard->(), qq{\n};
print q{$rcJohnGG->() - }, $rcJohnGG->(), qq{\n};
# Run the benchmark
#
cmpthese (50,
{
Cog => $rcCog,
JediWizard => $rcJediWizard,
JohnGG => $rcJohnGG
});
# JediWizard's date translation routine.
#
sub transDate
{
my $date = shift;
$date =~ s/(\d{2})-(\d{2})-(\d{4})/$3$2$1/;
return $date;
}
And these are the results
$rcCog->() - 13-01-2000
$rcJediWizard->() - 13-01-2000
$rcJohnGG->() - 13-01-2000
Rate JediWizard Cog JohnGG
JediWizard 6.00/s -- -0% -61%
Cog 6.00/s 0% -- -61%
JohnGG 15.2/s 153% 153% --
Looks like your hunch about speed was correct in that you and JediWizard pan out about the same (seems to go either way over several runs but the one I captured here was a dead heat). However, my simpler solution appears to be consistently quicker.
I hope this is of interest. Cheers, JohnGG |