[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
RE: [Omaha.pm] Sort quickie
Along these lines, here's something that I've stuck into most of my
scripts; whether it is actually used or not.
############################################################
# Sorting routine to sort by number
# below subroutine is equivalent to these 3 lines
# if($a < $b) { -1; }
# elsif($a == $b) { 0; }
# elsif($a > $b) { 1; }
############################################################
sub by_number {
$a <=> $b;
}
In use, it looks like this:
@numary = (2,9,5,4,30,21,11,10,1,7,215,"Two","Three","Four");
print "Sorted by ASCII\n";
foreach (sort @numary) {
print "$_\n";
}
print "\nSorted by number\n";
foreach (sort by_number @numary) {
print "$_\n";
}
Output is:
Sorted by ASCII
1
10
11
2
21
215
30
4
5
7
9
Four
Three
Two
Sorted by number
Three
Two
Four
1
2
4
5
7
9
10
11
21
30
215
Another interesting possibility, expanding on what Jay started;
it might be possible to use Jay's technique to sort IP addresses
without first converting the addresses to their "long int" form...
-Scott
-----Original Message-----
From: omaha-pm-bounces@pm.org [mailto:omaha-pm-bounces@pm.org]On Behalf
Of mØntar3
Sent: Saturday, June 19, 2004 6:29 PM
To: Perl Mongers of Omaha, Nebraska USA
Subject: Re: [Omaha.pm] Sort quickie
I use(d) that functionality to sort tabular data (two-dimensional
arrays, or an array hashes)---work(s|ed) well with CGI, allowing user(s)
to specify what column to sort on (and hides detail like comparisons of
text vs numerals vs dates in the called function). It's about as useful
as the Unix "find" utility.
Jay Hannah wrote:
>
> I had a bunch of hash keys that were dates in MMDDYYYY format. I
> wanted to get a sorted list of the keys. Perl to the rescue! Have
> y'all configured custom sort subroutines before? They're cool...
>
> The real code in context...
> ------------
> print "\n\nGroup pickup by cap_date (running total):\n";
> foreach (sort sort_by_cap_date keys %{$group_pickup{by_cap_date}}) {
> my $val = $group_pickup{by_cap_date}{$_};
> next if $val == 0;
> print "$_: $val\n";
> }
> }
>
> sub sort_by_cap_date ($$) {
> # We have to throw some mojo here since capdate is MMDDYYYY and
> obviously
> # we can't sort until we turn it into YYYYMMDD... -jhannah 6/14/04
> my ($a, $b) = @_;
> for ($a, $b) {
> s/(\d\d)(\d\d)(\d\d\d\d)/$3$1$2/;
> }
> $a <=> $b;
> }
> ---------------
>
> Same idea, distilled out to see the results easier and so you can play
> with it:
> ---------------
> my @dates = qw( 05012003 02012004 11012002 );
> print join ", ", sort @dates;
> print "\n";
> print join ", ", sort by_date @dates;
> print "\n";
>
> sub by_date ($$) {
> my ($a, $b) = @_;
> for ($a, $b) {
> s/(\d\d)(\d\d)(\d\d\d\d)/$3$1$2/;
> }
> $a <=> $b;
> }
> ----------------
>
> "sort" just does an ASCII sort, which isn't in date order for MMDDYYYY
> dates. Instead, "sort by_date" does a comparison after converting
> MMDDYYYY into YYYYMMDD, which does sort dates correctly. It doesn't
> munge the real values though.
>
> Neat, huh?
>
> perldoc -f sort
>
> j
>
> _______________________________________________
> Omaha-pm mailing list
> Omaha-pm@pm.org
> http://www.pm.org/mailman/listinfo/omaha-pm
>
_______________________________________________
Omaha-pm mailing list
Omaha-pm@pm.org
http://www.pm.org/mailman/listinfo/omaha-pm