A hash or an associative array is a special kind of list where pairs of consecutive elements are related or associated with one another. For example, we may want to associate the name of a person to his hometown, his height, or his weight. The following program uses four hashes.
Program 1.15
#!/usr/bin/perl
#file hashes.pl
use strict;
my (%hometowns, %heights, %weights, %ages, $friend);
%hometowns = ('Tommy' => 'Washington', 'Chad' =>'San Francisco',
'Jeff' => 'Boulder',
'Aaron' => 'Golden', 'Rick' => 'Montreal', 'Sean' => 'Montreal',
'Todd' => 'Colo Springs');
%heights = ('Tommy', 66, 'Aaron', 68, 'Rick', 67, "Chad", 73, 'Jeff', 70,
'Sean', 67, "Todd", 73);
%weights = ("Tommy" => 140, "Sean" => 140, "Todd" => 190, "Chad" => 180,
"Jeff" => 145,
"Aaron" => 155, "Rick" => 135 );
%ages = ('Aaron', 23, "Rick", 21, 'Tommy', 18, "Sean", 21, 'Chad', 23,
'Jeff', 21);
$weights {Aaron} = 157;
$ages {"Todd"} = 22;
$hometowns {'Tommy'} = 'Washington DC';
printf "%5s %15s %5s %5s %3s\n", "Name", "Hometown",
"Height", "Weight", "Age";
print "-" x 45, "\n";
foreach $friend (keys %hometowns){
printf "%5s %15s %3d %3d %2d\n", $friend, $hometowns{$friend},
$heights{$friend}, $weights{$friend}, $ages{$friend};
}
In Perl, the name of a hash variable must be preceded by the percentage sign (%). The first hash used in the program is %hometowns.
%hometowns = ('Tommy' => 'Washington', 'Chad' =>'San Francisco',
'Jeff' => 'Boulder', Aaron' => 'Golden', 'Rick' => 'Montreal',
'Sean' => 'Montreal', 'Todd' => 'Colo Springs');
It associates a person's name with a place. So, 'Tommy' is associated with 'Washington', and 'Chad' is associated with 'San Francisco'. In the first pair, 'Tommy' is the key and 'Washington' is the value. %hometown has seven keys associated with seven values. The usual syntax in Perl is to write an associated pair with the key first, followed by =>, and
the value. Key-value pairs are separated by commas. Each key or each value is scalar. The key is a string that can be single or double quoted. If the string is double-quoted, any variables inside are interpolated as usual. If we use => to separate a key from its corresponding value, it is not necessary to quote the key string. Perl automatically puts quotes around the key string in such a case. The key-value pairs can be specified in any order as long as the key and the corresponding value are together.
It is also possible to write a hash without using the => to separate a key from the associated value. A hash can be written just like a regular list where every element is separated from the next by a comma.
%ages = ('Aaron', 23, "Rick", 21, 'Tommy', 18, "Sean", 21, 'Chad', 23, 'Jeff', 21);
In such a case, the hash variable name must still start with % and the key strings must be quoted. Consecutive elements of the list are paired up as key and value.
Unlike a list, elements of a hash are not accessed using integer indices corresponding to positions. Elements of a hash are accessed using string-valued keys. For example, to access Tommy’s hometown, we write
$hometowns {'Tommy'}
The key is enclosed within braces ({ and }) instead of square brackets used with lists. The key may or may not be quoted. If it is not quoted, Perl automatically quotes it. Also note that the % sign in the name
of the hash must be changed to $ when we access an individual element of the hash. Once again, this is because in Perl, the $ prefix corresponds to a scalar and any value in a hash is scalar. In this case, the value of $hometowns {'Tommy'} happens to be 'Washington' after the initial assignment to the hash @hometowns.
We can change the value corresponding to a specific key in the hash. For example, in our program, the assignment
$hometowns {'Tommy'} = 'Washington DC';
changes the value associated with the key 'Tommy'
in the hash @hometowns to 'Washington DC' from the initial value of 'Washington'. We can also insert new key-value pairs into a hash table. In the program we are discussing, the initial assignment to the hash %ages does not have the key 'Todd'. But, we can add a pair by doing an assignment as we have done in the program.
$ages {"Todd"} = 22;
At the very end of the program there is a foreachloop.
foreach $friend (keys (%hometowns)){
printf "%5s %15s %3d %3d %2d\n", $friend, $hometowns{$friend},
$heights{$friend}, $weights{$friend}, $ages{$friend};
}
We have not seen foreach in our discussion so far. foreach takes a list and
loops over a block of expressions included inside curly brackets. In each iteration, the value of an iteration or index variable is set to the next element in the list. In the program fragment given above, the index variable is called $friend and the list over whose elements iterations take place is obtained as the result of a call to the keys function.
keys
keys (%hometowns)
returns the list
('Tommy', 'Chad', 'Jeff', 'Aaron', 'Rick', 'Sean', 'Todd');
as its result. It must be noted that when Perl returns the list of keys, the values need not come out in the order given above. They may come out in any order based on the internal hash function that Perl uses to store the hash.
So, in the program fragment given above, iteration takes place over this list of names. A name is taken and is assigned as the value of $friend and the printf statement inside the loop is performed. Here, Perl prints a name of a friend, and follows it by printing his hometown, height, weight and age.
The output of the program is given below.
Name Hometown Height Weight Age --------------------------------------------- Chad San Francisco 73 180 23 Rick Montreal 67 135 21 Aaron Golden 68 157 23 Todd Colo Springs 73 190 22 Jeff Boulder 70 145 21 Tommy Washington DC 66 140 18 Sean Montreal 67 140 21