#!/usr/bin/perl use strict; use warnings; # Constants (Operationally, if not functionally) my $MAXCHR = chr 255; my $HORRUL = '-------------------------------------------------------------------------------'; # Globals my $Maxval = ''; my @Unsorted = ( 'Dog', 'Cat', 'Bird', undef, 'Elephant', undef, 'Lizard' ); dumpArray("Original:", @Unsorted); # Build a maximum-value scalar: Length = longest + 1 # We will temporarily replace all undefined elements with this value # Since it is composed of all chr 255 values, it is the highest for sort # Since it is one character longer than the longest element, it uniquely # identifies the element as a former undef # Then sort can do its thing and we can detect these to convert back to undef my $maxlen = longestElement(@Unsorted); while (length($Maxval) <= $maxlen) { $Maxval .= $MAXCHR; } # Build a working copy of the array with undef replaced by $Maxval my @unsortedWork = (); foreach (@Unsorted) { if (defined $_) { push @unsortedWork, $_; } else { push @unsortedWork, $Maxval; } } # Sort, Convert modified entries back to undef, and show results my @sorted_custom = sort @unsortedWork; my @sorted_final = (); foreach (@sorted_custom) { if ($_ eq $Maxval) { push @sorted_final, undef; } else { push @sorted_final, $_; } } dumpArray("Custom Sort:", @sorted_final); exit; # Display an array with a title sub dumpArray { my ($dumpTitle, @dumpValues) = @_; print "$HORRUL\n$dumpTitle\n$HORRUL\n"; foreach my $dumpValue (@dumpValues) { if (defined $dumpValue) { print "$dumpValue\n"; } else { print "(undef)\n"; } } print "$HORRUL\n"; } sub longestElement { my $maxlen = 0; foreach(@_) { if (defined $_) { if (length > $maxlen) { $maxlen = length; } } } return $maxlen; }