Re: Sorting Dates Issue
by johngg (Canon) on Aug 18, 2010 at 17:37 UTC
|
Your idea of extracting year, month and day then concatenating them so they sort naturally is fine. You could take it a little further and apply a Guttman Rosler Transform instead of a sort routine. This node has an explanation and this is the paper on the technique. I think split might be an easier way of extracting date elements than a regex.
knoppix@Microknoppix:~$ perl -E '
> @dates = qw{
> 10/02/2004
> 02/01/2004
> 01/02/2004
> 01/06/2004
> 01/02/2005
> 01/12/2004
> 08/18/2010
> };
> say for
> map { substr $_, 8 }
> sort
> map { join q{}, ( split m{/} )[ 2, 0, 1 ], $_ }
> @dates;'
01/02/2004
01/06/2004
01/12/2004
02/01/2004
10/02/2004
01/02/2005
08/18/2010
knoppix@Microknoppix:~$
I hope this is of interest.
| [reply] [d/l] |
|
Yes it works, how could this code do the sorting in reverse, I mean the most recent date on top?
use strict;
my @dates = qw{
10/02/2004
02/01/2004
01/02/2004
08/18/2010
01/06/2004
01/02/2005
01/12/2004
};
my @sorted=
map { substr $_, 8 }
sort
map { join q{}, ( split m{/} )[ 2, 0, 1 ], $_ }@dates;
Thanks! | [reply] [d/l] |
|
knoppix@Microknoppix:~$ perl -E '
> @dates = qw{
> 10/02/2004
> 02/01/2004
> 01/02/2004
> 01/06/2004
> 01/02/2005
> 01/12/2004
> 08/18/2010
> };
> say for
> map { substr $_, 8 }
> sort { $b cmp $a }
> map { join q{}, ( split m{/} )[ 2, 0, 1 ], $_ }
> @dates;'
08/18/2010
01/02/2005
10/02/2004
02/01/2004
01/12/2004
01/06/2004
01/02/2004
knoppix@Microknoppix:~$
| [reply] [d/l] |
Re: Sorting Dates Issue
by ikegami (Patriarch) on Aug 18, 2010 at 15:42 UTC
|
The could you posted definitely did not produce the output you said it did. It doesn't even run. If you fix the errors that must be fixed simply to get your code to run (use strict, undeclared $c, undeclared $d), it works fine. Please post code you actually ran!! The code you posted is so far from what you really have, there's no way of telling what your problem is.
| [reply] |
Re: Sorting Dates Issue
by Utilitarian (Vicar) on Aug 18, 2010 at 15:47 UTC
|
You claim this is your code:
use strict;
...
sub compare {
$a =~ /(\d{2})\/(\d{2})\/(\d{4})/;
$c = $3 . $1 . $2;
$b =~ /(\d{2})\/(\d{2})\/(\d{4})/;
$c = $3 . $1 . $2;
$c <=> $d;
}
However there are no default variables $c or $d so your code would not run.
The fact that you assign the two compound numbers to the same variable may be your issue, use warnings; would have noted this.
print "Good ",qw(night morning afternoon evening)[(localtime)[2]/6]," fellow monks."
| [reply] [d/l] [select] |
Re: Sorting Dates Issue
by dasgar (Priest) on Aug 18, 2010 at 15:54 UTC
|
In your subroutine, you have $c <=> $d;. However, I don't see $d being declared or defined anywhere. I haven't tested your code, but this line looks like a good candidate for causing problems.
Also, you should change user strict; to use strict;, which I believe would have prevented you from using variables in your subroutine without using my or our. (see docs on strict)
| [reply] [d/l] [select] |
Re: Sorting Dates Issue
by jethro (Monsignor) on Aug 18, 2010 at 15:55 UTC
|
Please 'use warnings;', that would have brought you the following warnings:
Name "main::d" used only once: possible typo at ./t7.pl line 16.
Can't locate object method "user" via package "strict" (perhaps you fo
+rgot to load "strict"?) at ./t7.pl line 3.
And $d in the first warning is the problem, it is never set, instead you are setting $c twice
The other warning is because you wrote 'user' instead of 'use'
PS: Your sort line might be better written as my @ordered = sort compare @dates;. As you have it, sort calls the "block-subroutine" which in turn calls the compare subroutine. It is possible that perl optimizes this away but I wouldn't bet on it.
| [reply] [d/l] [select] |
|
Has anyone here sorted an array with dates to show how it can get done?
| [reply] |
|
I did test the script after correcting those two mistakes. Since the changes are trivial I didn't think it necessary to repost the script
| [reply] |
Re: Sorting Dates Issue
by murugu (Curate) on Aug 18, 2010 at 17:48 UTC
|
This is off topic. I never used a date module before. Tried with Date::Simple
use Date::Simple qw(:all);
my @dates = ('10/02/2004', '02/01/2004', '01/02/2004', '01/06/2004', '
+01/02/2005', '01/12/2004', '08/18/2010', '01/05/2005', '01/05/2004','
+01/05/2004');
@dates = map {$_->[0]} sort { &date($a->[1]) cmp &date($b->[1]) } map
+ {[$_, join '-',(split '/')[2,0,1]]} @dates;
print $_,$/ for (@dates);
Regards, Murugesan Kandasamy use perl for(;;);
| [reply] [d/l] |