
japhy
Enthusiast
Mar 23, 2000, 11:47 AM
Post #2 of 5
(516 views)
|
sort() defaults to ASCIIbetical order -- that is, by the value of a character in ASCII. "0" has a value of 48, "A" has a value of 65, and "a" has a value of 97. Thus, any string starting with "A" is sorted in front a string starting with "a". That also means that any string starting with "Z" is sorted in front of a string starting with "a". Example: <BLOCKQUOTE><font size="1" face="Arial,Helvetica,sans serif">code:</font><HR> sort (1, 2, 5, 10, 23) => (1, 10, 2, 23, 5) sort ("Zoo", "axe", 4) => (4, "Zoo", "axe") </pre><HR></BLOCKQUOTE> If you want to sort such that "Z" comes after "a", then you need to do sort case-insensitively: <BLOCKQUOTE><font size="1" face="Arial,Helvetica,sans serif">code:</font><HR> # method 1 @sorted = sort { lc($a) cmp lc($b) } @list; </pre><HR></BLOCKQUOTE> This tells sort() to compare its arguments via their lowercase representation. It can be a bit slow, though, because for a big list, it evaluates lc($a) and lc($b) many times. The next example, a Schwartzian transform, uses references to speed things up: <BLOCKQUOTE><font size="1" face="Arial,Helvetica,sans serif">code:</font><HR> # method 2; Schwartzian transform @sorted = map { $_->[1] } # the original string sort { $a->[0] cmp $b->[0] } # the lc() string map { [ lc($_), $_ ] } # [ lowercase, original ] @list; </pre><HR></BLOCKQUOTE> You can do even better, though, by using a Guttman-Rosler transform, which is good because it uses string tricks so that you DON'T pass any code to the sort() function, so you use Perl's internal sort(), which is a good thing: <BLOCKQUOTE><font size="1" face="Arial,Helvetica,sans serif">code:</font><HR> # method 3; Guttman-Rosler transform @sorted = map { substr($_, length($_)/2) } # second half of string (original string) sort map { lc($_) . $_ } # lowercase in front of original @list; </pre><HR></BLOCKQUOTE> I hope this helps you out. It was fun for me to write this. [This message has been edited by japhy (edited 03-23-2000).]
|