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
Replies are listed 'Best First'.
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 chanting in the Monastery: (14)
As of 2015-09-01 15:46 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My preferred temperature scale is:










    Results (33 votes), past polls