Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw
 
PerlMonks  

Sort on boredom

by Ovid (Cardinal)
on Mar 23, 2001 at 17:53 UTC ( #66620=perlmeditation: print w/ replies, xml ) Need Help??

Well, totally bored here at work. I have a bunch of VBScript code (ugh!) that's sitting here doing nothing until I get more specs. Thought I would use the time to play around with a problem suggested in another node. Essentially, the author wanted to sort a list by frequency of the items in that list. Having spare time and a huge desire to maintain my limited Perl skills, I wrote the following snippet:
use warnings; use strict; use Data::Dumper; my @vals = qw( 1 2 3 1 3 3 3 43 bob 2 bob 6 2 ); my %freqs; $freqs{$_}++ foreach @vals; my @sorted = map { $_->[0] } sort { $a->[1] <=> $b->[1] } map { [ $_, $freqs{ $_ } ] } keys %freqs; print Dumper( \@sorted );
Is there any way of eliminating the temporary variable %freqs? I hate synthetic code (code that solves a coding problem, not the problem the program is designed for) and it's bugging me. Or is this one of those age-old "FAQ" questions that I should already know the answer to?

Yeah, I know. It's a trivial post, but like I said, I am bored out of my skull here.

Incidentally, I am returning to the US in April (and will be programming in Perl again!!!!) and will be bidding a sad farewell to my newfound friends here in the Netherlands: kudra, ar0n, and h0mee (who was here visiting).

Cheers,
Ovid

Update: Once again, tilly makes me feel stupid :)

Join the Perlmonks Setiathome Group or just click on the the link and check out our stats.

Comment on Sort on boredom
Download Code
Re (tilly) 1: Sort on boredom
by tilly (Archbishop) on Mar 23, 2001 at 18:09 UTC
    Only inefficiently. If you don't tell Perl to build a hash lookup, you will have to repeatedly scan the array. But you can eliminate the Schwartzian sort:
    use strict; use Data::Dumper; $Data::Dumper::Indent = 1; my @vals = qw( 1 2 3 1 3 3 3 43 bob 2 bob 6 2 ); my %freqs; $freqs{$_}++ foreach @vals; my @sorted = sort { $freqs{$b} <=> $freqs{$a} or $a cmp $b } keys %freqs; print Data::Dumper->Dump([\@sorted], ['*sorted']);
    Remember that Schwarzian sorts are good when the sort step involves a lot of work. Hash lookups are not that much work. :-)

    Incidentally note that way I dump. I had looked that up a long time ago, but I want to start trying to use that for brief one-offs. I think it is rather nice to keep my names intact like that...

Re: Sort on boredom
by petral (Curate) on Mar 23, 2001 at 22:46 UTC
    Just for the heck of it:
    #!/usr/bin/perl -w use Data::Dumper; $Data::Dumper::Indent = 1; @vals = qw( 1 2 3 1 3 3 3 43 bob 2 bob 6 2 ); my @sorted = sort { $#$b <=> $#$a or $a cmp $b } keys %{{ map { @$_ = ( @$_, $_ ); $_ => 1 } @vals }}; print Data::Dumper->Dump([\@sorted], ['*sorted']);
    or as a 1-liner:
    perl -le '$,=", ";print sort { $#$b <=> $#$a or $a cmp $b}'\ -e 'keys %{{ map {@$_ = (@$_, $_); $_=>1} @ARGV}};'\ 0 _ __ 0 __ __ 0 0 00 @ % $ % ^ ^_ result-> 0, __, %, $, 00, @, ^, ^_, _


    p
      Heh. Awesome answer. You have convinced me that having temp variables can easily be clearer than an obsessive desire to eliminate "extraneous" code :)

      Cheers,
      Ovid

      Join the Perlmonks Setiathome Group or just click on the the link and check out our stats.

        Well, it did answer your question:
        Is there any way of eliminating the temporary variable %freqs?
        But it does add as many 'intermediate' arrays as there are uniq values. I guess that's not what you had in mind. Oh, well.

        p

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlmeditation [id://66620]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others cooling their heels in the Monastery: (5)
As of 2014-08-30 13:26 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The best computer themed movie is:











    Results (293 votes), past polls