At 3:03 PM -0400 10/21/02, Akens, Anthony wrote: >I'm attempting to use the following code to read a file >in the format of: > >directory name:displayname > >I want to sort the list by the "displayname", looking >at the first letter for each display name in the file. >If it's unique, I want to print it. This should result >in an alphabetical list of the letters for the display >names. However, the sort is not working quite right, >and I sometimes get letters out of order, missing, or >some that aren't even in the list. > >Can anyone tell me what I've done wrong?
First of all, it looks like you are sorting based on directory name, not on the "displayname", since you are sorting on the keys and the keys are the first part of the 'split /:/'. The second thing, is that you are only saving one value per 'directory name' -- if there is more than one file (assuming 'displayname' is the name of a file) in a directory, then you will only get the last file because your '$Names{$key} = $value;' is overwriting the previous value. If all you want is the list of unique letters that all the files start with, then you'd probably be better off with something much simpler, such as: ------------------------------------------------------------------- while (<NAMES>) { ($dir, $file) = split /:/; $letter = uc(substr($file, 0, 1)); $letters{$letter} = 1; # or $letters{$letter}++; to track the number } print "<P>"; foreach $letter (sort keys %letters) { print "<A HREF=\"\#$letter\">$letter<\/a> "; } ------------------------------------------------------------------- If you want to retain the list of files and the directory they are in and have them sorted by the displayname, then I'd do something like this (this assumes that the file names are case sensitive so we need to retain the case but we want the sort to be case insensitive): ------------------------------------------------------------------- while (<NAMES>) { ($dir, $file) = split /:/; $letter = uc(substr($file, 0, 1)); push(@{$files{$letter}}, [lc($file), $file, $dir]) } # # %files is now a hash array with keys that are the uppercase first letter # of the file names and the values are array references # # Each array reference contains array references which contain # the file name in lower case, the file name in the original case, # and the dir name in the [0] and [1] positions # print "<P>"; # print out the index foreach $letter (sort keys %files) { print "<A HREF=\"\#$letter\">$letter<\/a> "; } # print out the file list foreach $letter (sort keys %files) { print "<h2><a name=\"$letter\">$letter</a></h2>\n"; foreach $file_ref (sort {$a->[0] cmp $b->[0]} @{$files{$letter}}) { print "$file_ref->[2]:$file_ref->[1]<br>\n"; } } ------------------------------------------------------------------- Note that the conversion to upper or lower case only occurs once when we are saving the file info. If you do the conversion in the sort block, perl may end up doing the conversion on every comparison (unless it caches the comparison values which it may well do). This comes at the expense of having to save the converted filename, so if for some reason you are tight on memory (i.e. 1000s of filenames) and have lots of CPU cycles to spare, then you might not want to save it and do the case conversion in the sort block. There are, of course, lots of variations on this that will work just as well! ---Larry +------------------------------------------------------------------------+ | Larry Coffin, G.P.H. Watertown, MA | | http://www.PointInfinity.com/lcoffin/ [EMAIL PROTECTED] | +------------------------------------------------------------------------+ Demographic polls show that you have lost credibility across the board. Especially with those 14 year-old Valley girls. - -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]