I really wish you would have included some sample data - it
doesn't have to be the exact data for obvious legal reasons,
but just some data of similar structure. This code is quite
horrible, it is obvious that someone was attempting to make
modular, reusable code, but fell short of the mark.
Looks like the idea is to sort on the results of a user
defined sort routine (that relies on global variable no less)
that gets its input from a subroutine that turns its first
argument into a filehandle and returns it. This is wrong,
wrong, wrong, wrong!
Instead, you should open the file, process it into a data
structure - looks like a 2-d array would be good to me, THEN
sort the data structure. The subroutine sort_func is
repeatedly splitting the lines to do it's work - this is
extremely wasteful, especially if you need the pieces of
the lines again later on.
Here is some sample code to play with. Since you didn't
supply any test data (hint hint), i'll make up my own. Also,
i am going to use the DATA handle instead of reading from
a file. You should have no troubles changing this to fit
your needs:
use strict;
my $datafields = 3;
my $item_no = 2;
my @records;
# read from DATA - any filehandle will do . . .
foreach my $line (<DATA>) {
chomp $line;
push @records, [ split(/\s+/,$line,$datafields) ];
}
=comment
now @records looks like this:
@records = (
['foo','gabba','12'],
['bar','hey','2'],
['baz','gabba','38']
);
the elements in []'s are array references
now store the array references based on the order
of the 3rd element, which is a number - numbers
are compared with the <=> operator, strings are
comparted with the cmp operator - $a and $b are
magic variables that contain the two items being
compared - if you want ascending order, compare
$a to $b - for descencing order, compare $b to $a
=cut
my @sorted = sort { $b->[$item_no] <=> $a->[$item_no] } @records;
=comment
that's it! now print out the results - the tricky part
is that @sorted is a list of list REFERENCES, so we need
to do some extra work to de-reference them
=cut
foreach my $line (@sorted) {
print join(', ', @$line), "\n";
}
=comment
the following would normally be found in a data file.
i originally delimited these values with tabs, but they
will probably turn into spaces when you copy and paste
that's why i used /\s+/ instead of /\t/ in split above
=cut
__DATA__
foo gabba 12
bar hey 2
baz gabba 38
Hope this helps, and don't forget to erase the comments
when you are done ;)
jeffa
L-LL-L--L-LL-L--L-LL-L--
-R--R-RR-R--R-RR-R--R-RR
F--F--F--F--F--F--F--F--
(the triplet paradiddle)
UPDATE - changed multi-line comment style from # to POD |