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!pashdowntchrist@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.
--tommerlyn@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'..."====/