[Koha-patches] [PATCH] Add undef-tolerant and number-respecting sort function.
Joe Atzberger
joe.atzberger at liblime.com
Thu Dec 18 04:36:06 CET 2008
---
C4/Reports.pm | 113 +++++++++++++++++++++++++++++++++++++++++++++------------
1 files changed, 90 insertions(+), 23 deletions(-)
diff --git a/C4/Reports.pm b/C4/Reports.pm
index d0bbe70..ce73f71 100644
--- a/C4/Reports.pm
+++ b/C4/Reports.pm
@@ -18,12 +18,12 @@ package C4::Reports;
# Suite 330, Boston, MA 02111-1307 USA
use strict;
+use warnings;
use CGI;
use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
use C4::Context;
use C4::Debug;
-# use Smart::Comments;
# use Data::Dumper;
BEGIN {
@@ -33,31 +33,10 @@ BEGIN {
@ISA = qw(Exporter);
@EXPORT = qw(
GetDelimiterChoices
+ NumberOrStringSort
);
}
-=head1 NAME
-
-C4::Reports - Module for generating reports
-
-=head1 DESCRIPTION
-
-This module contains functions common to reports.
-
-=head1 EXPORTED FUNCTIONS
-
-=head2 GetDelimiterChoices
-
-=over 4
-
-my $delims = GetDelimiterChoices;
-
-=back
-
-This will return a list of all the available delimiters.
-
-=cut
-
sub GetDelimiterChoices {
my $dbh = C4::Context->dbh;
@@ -81,10 +60,98 @@ sub GetDelimiterChoices {
-multiple => 0 );
}
+sub NumberOrStringSort {
+ my $a = shift;
+ my $b = shift;
+ # first we need to bail out if either element is undef
+ # print STDERR sprintf "sorting %5s vs. %5s\n", (defined($a) ? $a : "UNDEF"), (defined($b) ? $b : "UNDEF");
+ defined($a) or return (defined($b) ? -1 : 0);
+ defined($b) or return 1;
+ ($a =~ /^\-?\d+$/ and $b =~ /^\-?\d+$/) and return $a <=> $b;
+ # so if both elements look like numbers, sort them numerically
+ return $a cmp $b; # else revert to string sort order
+}
+
1;
__END__
+=head1 NAME
+
+C4::Reports - Module for generating reports
+
+=head1 DESCRIPTION
+
+This module contains functions common to reports.
+
+=head1 EXPORTED FUNCTIONS
+
+=head2 GetDelimiterChoices
+
+=over 4
+
+my $delims = GetDelimiterChoices;
+
+=back
+
+This will return a list of all the available delimiters.
+
+=head2 NumberOrStringSort
+
+=over 4
+
+my @array = sort {NumberOrStringSort($a,$b)} @array;
+
+=back
+
+Used to compel sort order that respects numbers. That is, it doesn't sort 11 ahead of 2. All numbers will sort out
+to an earlier group before non-numerical strings. It can also handle undefined elements.
+
+Test it with:
+perl -we 'use C4::Reports;
+ my @x=(3,12,2,undef,,114,1,-1,-20,"foo",14,"bar",101,undef);
+ print "\n", scalar(@x), " elements:\n",
+ map {defined($_) ? "$_\n" : "UNDEF\n"}
+ sort {NumberOrStringSort($a,$b)} @x;'
+
+The output should look like:
+ 13 elements:
+ UNDEF
+ UNDEF
+ -20
+ -1
+ 1
+ 2
+ 3
+ 12
+ 14
+ 101
+ 114
+ bar
+ foo
+
+Comparing this to the output of regular sort, you would first get 9 warnings like:
+ Use of uninitialized value in sort at -e line 1.
+
+Then the output would be:
+ 13 elements:
+ UNDEF
+ UNDEF
+ -1
+ -20
+ 1
+ 101
+ 114
+ 12
+ 14
+ 2
+ 3
+ bar
+ foo
+
+NumberOrStringSort is not really specific to Reports, so it is conceivable it should
+move to a broader Utility class.
+
=head1 AUTHOR
Jesse Weaver <jesse.weaver at liblime.com>
--
1.5.5.GIT
More information about the Koha-patches
mailing list