rkrebs@fantasy.dsd.es.com (Randall Krebs) (04/06/91)
In article <1991Apr5.183701.21325@javelin.sim.es.com> pashdown@javelin.sim.es.com (Pete Ashdown) writes: How do I go about sorting an associative array, not by the string, but by the associated value? For example, how would I change following 'word count' program to sort by occurance rather than alphabetically? (From the Nutshell Book) while (<>) { s/-\n//g; tr/A-Z/a-z/; @words = split (/\W*\s+\W*/, $_); foreach $word (@words) { $wordcount {$word}++; } } foreach $word (sort keys(%wordcount)) { printf "%20s %d\n", $word, $wordcount{$word}; } Try: sub freqsort { $wordcount{$a} <=> $wordcount{$b}; } foreach $word (sort(freqsort keys(%wordcount))) { printf "%20s %d\n", $word, $wordcount{$word}; } randall. -- Randall S. Krebs | "If you don't drink, don't drive. (rkrebs@dsd.es.com) | And if you don't read the man Evans & Sutherland Computer Corporation | page, don't run the program." Salt Lake City, Utah (Where?) | - Sister Admin
pashdown@javelin.sim.es.com (Pete Ashdown) (04/06/91)
How do I go about sorting an associative array, not by the string, but by the associated value? For example, how would I change following 'word count' program to sort by occurance rather than alphabetically? (From the Nutshell Book) while (<>) { s/-\n//g; tr/A-Z/a-z/; @words = split (/\W*\s+\W*/, $_); foreach $word (@words) { $wordcount {$word}++; } } foreach $word (sort keys(%wordcount)) { printf "%20s %d\n", $word, $wordcount{$word}; } -- / "Uhh" - Jon Bon Jovi \ HARHARHARHARHARHARHARHARHAR \\ / AMGIA!! The computer for the mind. \X v// HAR(This space for rent)HAR |XV [FREE CD'S! SEND ME MONEY!] X\/ HARHARHARHARHARHARHARHARHAR Pete Ashdown pashdown@javelin.sim.es.com ...uunet!javelin.sim.es.com!pashdown
tchrist@convex.COM (Tom Christiansen) (04/06/91)
From the keyboard of pashdown@javelin.sim.es.com (Pete Ashdown): :How do I go about sorting an associative array, not by the string, but by :the associated value? For example, how would I change following 'word count' :program to sort by occurance rather than alphabetically? : :foreach $word (sort keys(%wordcount)) { : printf "%20s %d\n", $word, $wordcount{$word}; :} The most straight-forward way is to declare a function that given keys, compares values. For example: sub by_value { $wordcount{$a} <=> $wordcount{$b}; } foreach $word (sort by_value keys %wordcount) { printf "%20s %d\n", $word, $wordcount{$word}; } A minor problem with this method is that the array to compare is hardcoded in. You can avoid this by using dynamic scoping. I'll also use pass-by-name for efficiency. sub _by_value { $table{$a} <=> $table{$b}; } sub sort_by_value { local(*table) = @_; sort _by_value keys %table; } foreach $word (&sort_by_value(*wordcount)) { printf "%20s %d\n", $word, $wordcount{$word}; } Another possibilty, which I don't care for as much, is to dynamically declare the &by_value function using an eval. This is left as an exercise for the reader. :-) I guess I'd better keep the sorting section in my perl tutorial after all. --tom
merlyn@iwarp.intel.com (Randal L. Schwartz) (04/06/91)
In article <1991Apr5.183701.21325@javelin.sim.es.com>, pashdown@javelin (Pete Ashdown) writes: | | How do I go about sorting an associative array, not by the string, but by | the associated value? For example, how would I change following 'word count' | program to sort by occurance rather than alphabetically? | | (From the Nutshell Book) | | while (<>) { | s/-\n//g; | tr/A-Z/a-z/; | @words = split (/\W*\s+\W*/, $_); | foreach $word (@words) { | $wordcount {$word}++; | } | } | | foreach $word (sort keys(%wordcount)) { foreach $word (sort bywordcount keys(%wordcount)) { | printf "%20s %d\n", $word, $wordcount{$word}; | } sub bywordcount { $wordcount{$a} <=> $wordcount{$b}; # use spaceship operator for numeric } See the sort operator description on page 180 of The Book. @a=('hacker,',Just,Perl,another);@a=grep($_=splice(@a,$_,1),1,2,1,0);print"@a" -- /=Randal L. Schwartz, Stonehenge Consulting Services (503)777-0095 ==========\ | on contract to Intel's iWarp project, Beaverton, Oregon, USA, Sol III | | merlyn@iwarp.intel.com ...!any-MX-mailer-like-uunet!iwarp.intel.com!merlyn | \=Cute Quote: "Intel: putting the 'backward' in 'backward compatible'..."====/