in reply to count sort & output

An OO-style solution:
test.pl: use hot_web; use strict; my $hot = new hot_web; $hot->count("www.yahoo.com","200"); #set to 200 $hot->count("www.yahoo.com","+20"); #add 200 $hot->count("www.yahoo.com"); #increase by 1 $hot->count("www.google.com","3000"); #set 20 3000 $hot->count("www.google.com","+300"); #add 300 $hot->display; hot_web.pm: package hot_web; use strict; sub new { my $self = {}; bless $self; return $self; } sub count { my $self = shift; my $url = shift; if (@_) { my $count = shift; if ($count =~ /^\+/) { $self->{$url} += $count; } else { $self->{$url} = $count; } } else { $self->{$url} ++; } } sub display { my $self = shift; print "Hot Webs:\n"; foreach (sort {$self->{$a} < $self->{$b}} keys %{$self}) { print "$_ appears: $self->{$_} time(s)\n"; } } 1;

Replies are listed 'Best First'.
Re: Re: count sort & output
by jdporter (Paladin) on Dec 19, 2002 at 03:29 UTC
    if (defined($hash{$key}) { $hash{$key} ++; } else { $hash{$key} = 1; }
    That's actually more work than necessary.
    All you need is     $hash{$key}++; because if the element doesn't yet exist, it will be created and initialized ("autovivified") to undef, then the undef will be nummified to 0, then the 0 will be incremented to 1.

    %hash = ("www.yahoo.com", 10, "www.google.com", 2000); foreach (keys %hash) { $rev_hash{$hash{$_}} = $_; } foreach (sort keys %rev_hash) { print "$rev_hash{$_} appears: $_ time(s)\n"; }
    No, that's bad. What if both yahoo and google have a value of 100?
    All you're really trying to do it print out the entries sorted by value, numerically.
    (And, btw, you were sorting lexically, which is also wrong.)
    %hash = ( www.yahoo.com => 10, www.google.com => 2000, ); for ( sort { $hash{$a} <=> $hash{$b} } keys %hash ) { print "$_ appears: $hash{$_} time(s)\n"; }

    jdporter
    ...porque es dificil estar guapo y blanco.

Re^2: count sort & output
by Aristotle (Chancellor) on Dec 19, 2002 at 08:39 UTC
    I don't want to put down the effort you put into this, but using OO for this a task seems like overkill. How is
    $hot->count("www.yahoo.com","200"); #set to 200 $hot->count("www.yahoo.com","+20"); #add 200 $hot->count("www.yahoo.com"); #increase by 1
    any better than a hash?
    $hot{"www.yahoo.com"} = 200; $hot{"www.yahoo.com"} += 20; $hot{"www.yahoo.com"}++

    Note also how the latter makes it immediately obvious what's going on - you don't have to look up a classes' behaviour to know what it does.

    Lastly, if I did take the OO route for some reason - maybe because I need to pass this around a lot of places in my program, and maybe it does a lot more on-the-fly calculation than just counting mentions, or something - I'd prefer an interface like this:

    $hot->count("www.yahoo.com")->set(200); $hot->count("www.yahoo.com")->add(20); $hot->count("www.yahoo.com")->inc;

    Makeshifts last the longest.