--- trunk/webwork2/lib/WeBWorK/Utils.pm 2003/06/10 22:40:36 1110 +++ trunk/webwork2/lib/WeBWorK/Utils.pm 2003/06/10 23:05:57 1111 @@ -35,8 +35,7 @@ decodeAnswers encodeAnswers ref2string - dequoteHere - wrapText + sortByName ); sub runtime_use($) { @@ -142,29 +141,6 @@ return defined $soFar ? $soFar : 0; } -# ----- - -#sub dbDecode($) { -# my $string = shift; -# return unless defined $string and $string; -# my %hash = $string =~ /(.*?)(? and cmp operators return -1 if the left operand is less than the +# right operand, 0 if they are equal, and +1 if the left operand is greater +# than the right operand. + +sub sortByName { + my ($field, @items) = @_; + return sort { + my @aParts = split m/(?<=\D)(?=\d)|(?<=\d)(?=\D)/, $a->$field; + my @bParts = split m/(?<=\D)(?=\d)|(?<=\d)(?=\D)/, $b->$field; + while (@aParts and @bParts) { + my $aPart = shift @aParts; + my $bPart = shift @bParts; + my $aNumeric = $aPart =~ m/^\d*$/; + my $bNumeric = $bPart =~ m/^\d*$/; + + # numbers should come before words + return -1 if $aNumeric and not $bNumeric; + return +1 if not $aNumeric and $bNumeric; + + # both have the same type + if ($aNumeric and $bNumeric) { + next if $aPart == $bPart; # check next pair + return $aPart <=> $bPart; # compare numerically + } else { + next if $aPart eq $bPart; # check next pair + return $aPart cmp $bPart; # compare lexicographically + } + } + return +1 if @aParts; # a has more sections, should go second + return -1 if @bParts; # a had fewer sections, should go first + } @items; +} + 1;