Hashes #7

#0 | #1 | #2 | #3 | #4 | #5 | #6 | #7

Hashes as Look-up Tables

Looping is a common occurrence in programming, and there are several ways to perform this function. However, in some cases using a hash in a particular way is a better choice.

For example, we have all had to write code where a string variable is checked against a number of variables for a match.

Here we present a case where we want to translate words into the proper letter (from our introduction to arrays).

A common way to do this is a cascading set of 'if .. elsif' statements:

sub words_to_lets {
     my ($words) = @_;
     my @words = split /\s+/, $words;
     
     # translate each word into appropriate number
     my $letter = "";
     for my $word (@words) {
          if ($word =~ m/ alpha /ixms) {
               $letter .= 'a';
          }
          elsif ($word =~ m/ bravo /ixms) {
               $letter .= 'b';
          }
          elsif ($word =~ m/ charlie /ixms) {
               $letter .= 'c';
          }
          elsif ($word =~ m/ delta /ixms) {
               $letter .= 'd';
          }
          elsif ($word =~ m/ echo /ixms) {
               $letter .= 'e';
          }
          elsif ($word =~ m/ foxtrot /ixms) {
               $letter .= 'f';
          }
#    etc.
          elsif ($word =~ m/ yankee /ixms) {
               $letter .= 'y';
          }
          elsif  ($word =~ m/ zulu /ixms) {
               $letter .= 'z';
          }
     }
     return $letter;
}
print words_to_lets('bravo echo echo foxtrot') . "\n"; # beef

Using a hash as a look-up seems cleaner and is more efficient:

my %lets_for = (
     "alpha"   => "a",
     "bravo"   => "b",
     "charlie" => "c",
     "delta"   => "d",
     "echo"    => "e",
     "foxtrot" => "f",
# etc
     "yankee"  => "y",
     "zulu"    => "z",
     );
sub words_to_lets {
     my ($words) = @_;     
     # split each word
     my @words = split /\s+/, $words;
     # translate to proper number
     my $WORD = q{}; # empty string
     for my $word (@words) {
          my $letter = $lets_for{lc $word};
          if (defined $letter) {
               $WORD .= $letter;
          }
     }
     return $WORD;
}
print words_to_lets('bravo echo echo foxtrot') . "\n"; # beef

I'm not sure about you, but I find this method a lot easier to read, and there is less typing (so less chance of errors). And we already know that hashes are very efficient.