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