Sorting Strings Ending In Numbers In Perl

Synopsis

I deal with a lot of names that look like “somedumbserver2” and “somedumbserver15”. Using Perl’s default sort, “somedumbserver2” comes before “somedumbserver15” because the character “2” is greater than the character “1”, and that’s where the sort stops.  This sort, “snsort” or “string-number sort”, is a little wiser, and all else being equal compares the number “2” to the number “15”, and properly orders it. It’s also safe to use if some strings don’t conform to this pattern.

I wrote this to be a Vmethod to list objects in Template Toolkit, so I kept the surrounding code intact in case anyone wants to use it as-is, but “sub sns” can be taken out and put in any Perl program, and used in conjunction with the Perl “sort” function.

Code

$Template::Stash::LIST_OPS->{ snsort } = sub {
        my $list = shift;
        return sort sns @$list;
        
        sub sns {
                my @aparts=$a =~ /^(\D+)(\d+)$/;
                my @bparts=$b =~ /^(\D+)(\d+)$/;
                
                return $a cmp $b unless @aparts and @bparts; # Safety
                return $aparts[0] cmp $bparts[0] unless $aparts[0] eq $bparts[0];
                return $aparts[1] <=> $bparts[1];
        }
};
This entry was posted in Coding, Linuxy and tagged , , . Bookmark the permalink.

1 Response to Sorting Strings Ending In Numbers In Perl

  1. Paul Graham says:

    I was dealing with this issue as well, and couldn’t figure out a good solution for what at first seemed like an easy problem. Thanks for posting your algorithm, its exactly what I needed!

Leave a Reply

Your email address will not be published. Required fields are marked *