in reply to sorting by field of a tab-delimited hash value
You could certainly take that approach, but this might also be a good time to learn about the Schwartzian Transform. Using that technique will allow each element to be processed only once during the sort (which could be important for large lists of data that require expensive processing prior to sorting, but may not result in much of a time savings for your specific application). For example:
foreach my $id ( map { $_->[1] } sort { $a->[0] <=> $b->[0] } map { [ (split( "\t", $students{$_} ))[1], $_ ] } keys %students ) { printf "$id\t$students{$id}\n"; }
This prints:
Note that the leading zeros are left off of the student IDs. If you want them retained, printf will do the trick nicely: printf( "%04d\t$students{$id}\n", $id );4873 Tom 2.9 236 Fred 3.2 1522 Susan 4.0
Update: Since what is going on in the guts of the ST might be less than clear, here is a brief explanation (start reading from the second map and proceed upward):
The list of student IDs, now sorted by GPA, are what the foreach loop uses for printing. There are many other WTDI, of course. :-)# Create a list of student IDs by taking the sorted # list of anonymous arrays and returning the second # element of each. map { $_->[1] } # Sort the list of anonymous arrays (created below) # numerically, using the first element in the array # (the GPA). sort { $a->[0] <=> $b->[0] } # For each key in %students, create an anonymous array: # The first element is the GPA, obtained by taking # the second element of the list created by splitting # the value of $students{$_} on the tab, and the second # element is the student ID. map { [ (split( "\t", $students{$_} ))[1], $_ ] } keys %students )
HTH
|
|---|