in reply to Re: Re: Sorting question...
in thread Sorting question...
First, the first "paragraph" of code:
my @records; # Declare an array to hold records from the input file. { # Start a new lexical block to limit the scope # of the next line. local $/ = "\n\n"; # Set the input record separator to # be a blank line. This allows you to read # records in, delimited by blank lines. open IN, "<file.dat" or die "Cannot open data file.\n$!"; # Open the input file for reading. Die if an error occur +s. while ( my $record = <IN> ) { # Read the file in record by record, into $record. my @kv_pairs = split /\n/, $record; # Split each record into its six lines, and store # each line as an array element. push @records, [@kv_pairs]; # Create an anonymous array that is a copy of @kv_pairs. # Push the anonymous array containing a complete set # of keys/values for a given record into the @records arr +ay # as an array of arrays. } # End the while loop. close IN; # Close the infile, we're done with it. } # Close the lexical block that constrains the # effects of the "local $/ = ....." definition.
Ok, that's the paragraph that builds up a datastructure containing a list of records from your input file. Now we need to sort them. To do so, we use a Schwartzian Transform. The transform puts your original data structure into a container where each element is paired up with the one thing you wish to sort by. The idea is that you sort by some criteria, and then strip away the sort criteria before handing the original datastructure back, in sorted order. I guess I'm not all that good at explaining it. When reading the commented code below, start from the LAST map, and read backward. Or in other words, the last occurrence of map is feeding data to sort, which is feeding data to the first occurrence of map. Here's the fully commented code:
my @sorted_recs = map { $_->[0] } # This first map executes last, after the sort is done. # it strips away the datastructure container along with the # sort criteria information, leaving only the original # datastructure, in sorted order. sort { $a->[1] <=> $b->[1] } # Sort executes after the second map is done. Sort is being told # to sort on the floating point number being used as the # sort criteria. map { [ $_, (split /:\s*/, $_->[3])[1] ] } # The final map executes first. It creates a container # datastructure. Each element contains an array ref to a two # element array. The first element is your original record. # The second element contains only the floating point # number you're trying to sort on. @records;
I really hope this helps. If you ask specific questions as to which part of it you are having trouble understanding I'm happy to help. The whole thing would have been Greek to me before I really dug in and started reading everything I could find about Perl (and experimenting a lot, and participating here). Good luck. It's a fun ride.
Dave
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Re: Re: Re: Sorting question...
by Anonymous Monk on Jan 17, 2004 at 20:34 UTC |