#!/usr/bin/perl -w # # rev-sort -- 1999-04-19 # # inspired by a question on #perl, this program sorts a list of "file # revisions". # use strict; sub rev_sort { # get a ref to the array we were sent my $in_ref = shift; # split each revision on periods. so "3.2.4" -> [ 3, 2, 4] my @keys = map { [$_, [ split /\./ ] ] } @$in_ref; # now to do the sort. my @rv = sort { # first, get the split-up array refs my $ar = $a->[1]; my $br = $b->[1]; # and the "max index" to go to my $m = ($#$ar > $#$br) ? $#$ar : $#$br; # these need to be in the outer scope, since we're going to # compare them after we leave the "for" loop my ($xa, $xb); INNER_CMP: for (my $i = 0; $i <= $m; ++$i) { # get the appropriate values from each array $xa = ($#$ar < $i) ? -1 : $ar->[$i]; $xb = ($#$br < $i) ? -1 : $br->[$i]; # and loop again if they're equal last INNER_CMP unless $xa == $xb; } # since these were the first unequal ones (or, if they're # identical, we ran off the end of the loop), the comparison # between these two is the appropriate one. $xa <=> $xb; } @keys; # input source... this *is* a sort, after all # get rid of the splits. return map { $_->[0] } @rv; } # read in sample data my @test = ; chomp @test; $" = ", "; # man perlvar ... put a comma when we expand arrays in # strings. print "before: [@test]\n"; my @sorted = rev_sort \@test; print "after: [@sorted]\n"; exit; __END__ 1.0 1.1 6.12 10.4 10.0.3 1.1.1 1.1.2 2.3 1.3 1.4 3.1 3.2 4.5 1.5 1.5.0 1.5.2