Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW
 
PerlMonks  

(jeffa) Re: Sorting Numbers

by jeffa (Bishop)
on Nov 06, 2001 at 07:13 UTC ( [id://123491]=note: print w/replies, xml ) Need Help??


in reply to Sorting Numbers

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

Replies are listed 'Best First'.
Re: (jeffa) Re: Sorting Numbers
by Devo (Initiate) on Nov 06, 2001 at 10:36 UTC

    Yes, I do agree with your idea of simplicity...Open the file, dump in an array, then sort. I would like to solve it in two ways however, and avoid editing so much of the scripts. (This is a series of about 6 different scripts *reaching for aspirin*, all with user defined variables linked together in very odd ways....hence the problem I'm having here).

    The data is tab deliminated and looks like this:

    17 8/10/01 Joe Blow Joe@Blow.com New York webtherapist www.d +rudgereport.com I like green-eggs and ham,etc...

    That's meant to be perceived as 8 different fields, the first being the number of the entry in which I wish to sort by...descending order of course.

      From the perspective of sheer laziness, would it work to replace the
      "local ($a, $b) = @_"
      with a
      "local ($b, $a) = @_"
      ? Reversed sort order, no comprehension or re-writing required.

      /s

        Except of course $a and $b aren't actually passed into the sort function like that. Which is presumeably why that line is commented out :-)

        Blessed Be
        The Pixel

      I understand the motive of trying to avoid editing the scripts, Devo, but in the long run if you stick with the previous author's plan, it's too fragile to maintain and impossible to safely extend.

      tilly wrote a nice discussion of Pass by reference vs globals, in a thread of nice discussions that's relevant to the maintenance problem you are facing (thus the need of aspirin)

      The true virtue of laziness is in saving everyone work. It is the most lazy thing, in this case, to edit out the costly, polluting mistakes in that code
      mkmcconn

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://123491]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others avoiding work at the Monastery: (3)
As of 2024-03-29 14:18 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found