[Omaha.pm] Sort quickie

Miller, Scott L (Omaha Networks) scott.l.miller at hp.com
Wed Jul 7 15:07:01 CDT 2004


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 at pm.org [mailto:omaha-pm-bounces at 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 at pm.org
> http://www.pm.org/mailman/listinfo/omaha-pm
>
_______________________________________________
Omaha-pm mailing list
Omaha-pm at pm.org
http://www.pm.org/mailman/listinfo/omaha-pm




More information about the Omaha-pm mailing list