to DO or not to DO, that is the question
December 6, 2009
Following on from yesterdays post about do blocks, this is what I would normally do off the bat:
sub word_freq {
my %words;
$words{$_}++ for split /\s+/, lc $_[0];
\%words;
}
Returning back a hash reference is both leaner and meaner
use List::Util qw(sum);
my $s = "The green hat is tHe twin of the green hat";
my $num_of_hats = word_freq( $s )->{ hat }; # word count just for 'hat'
# don't worry... always unique hashrefs returned:
my $hash_ref = word_freq( $s );
my $hash_ref2 = word_freq( $s );
# thus you can safely:
$hash_ref2->{green} = 100;
say "$hash_ref->{green} : $hash_ref2->{green}"; # => "2 : 100"
# clean copy for those who prefer there hashes not to be hashrefs!
my %hash = %{ word_freq( $s ) };
# returns ( 'is', 'of')
my @two_letter_words = grep { length $_ == 2 } keys %{ word_freq( $s ) };
# number of "green" + "hat" == 4
my $green_plus_hat = sum @{ word_freq( $s ) }{ qw/green hat/ };
And what I probably wouldn’t do is:
use List::MoreUtils qw(uniq);
my $s = "The green hat is tHe twin of the green hat";
my %words = do {
my @words = split /\s+/, lc $s;
map {
my $word = $_;
$word => scalar grep { $_ eq $word } @words;
} uniq @words
};
I actually prefer the code aesthetics of this but the extra cycle (grep) through @words pushes me towards the leaner hash counting solution. Horses for courses?
/I3az/
No comments yet


