5.5. Hash (Associative Array) Functions
5.5.1. The keys Function
The keys function returns, in random order, an array whose elements are the keys of a hash (see "The values Function" and "The each Function").
keys(ASSOC_ARRAY)
keys ASSOC_ARRAY
Example 5.53.
(In Script)
# The keys function returns the keys of a hash
1 %weekday= (
'1'=>'Monday',
'2'=>'Tuesday',
'3'=>'Wednesday',
'4'=>'Thursday',
'5'=>'Friday',
'6'=>'Saturday',
'7'=>'Sunday',
);
2 foreach $key ( keys(%weekday) ){print "$key ";}
print "\n";
3 foreach $key ( sort keys(%weekday) ){print $key ;}
print "\n";
(Output)
2 7 1 2 3 4 5 6
3 1 2 3 4 5 6 7
The hash %weekday is assigned keys and values. For each value in %weekday, call the keys function to get the key. Assign the key value to the scalar $key and print it in random order. Now the keys are sorted and printed.
|
|
5.5.2. The values Function
The values function returns, in random order, an array consisting of all the values of a hash.
values(ASSOC_ARRAY)
values ASSOC_ARRAY
Example 5.54.
(In Script)
# The values function returns the values in a hash
1 %weekday= (
'1'=>'Monday',
'2'=>'Tuesday',
'3'=>'Wednesday',
'4'=>'Thursday',
'5'=>'Friday',
'6'=>'Saturday',
'7'=>'Sunday',
);
2 foreach $value ( values(%weekday)){print "$value";}
print "\n";
(Output)
2 Monday Tuesday Wednesday Thursday Friday Saturday Sunday
The hash %weekday is assigned keys and values. For each value in %weekday, call the values function to get the value associated with each key. Assign that value to the scalar $value, and print it to STDOUT.
|
|
5.5.3. The each Function
The each function returns, in random order, a two-element array whose elements are the key and the corresponding value of a hash.
Example 5.55.
Code View: (In Script)
#! /usr/bin/perl
# The each function retrieves both keys and values from a hash
1 %weekday=(
'Mon' => 'Monday',
'Tue' => 'Tuesday',
'Wed' => 'Wednesday',
'Thu' => 'Thursday',
'Fri' => 'Friday',
'Sat' => 'Saturday',
'Sun' => 'Sunday',
);
2 while(($key,$value)=each(%weekday)){
3 print "$key = $value\n";
}
(Output)
3 Sat = Saturday
Fri = Friday
Sun = Sunday
Thu = Thursday
Wed = Wednesday
Tue = Tuesday
Mon = Monday
The hash %weekday is assigned keys and values. The each function returns each key and its associated value of the %weekday hash. They are assigned to the scalars $key and $value, respectively. The keys and values are printed but in an unordered way.
|
|
5.5.4. Sorting a Hash
When sorting a hash, you can sort the keys alphabetically very easily by using the built-in sort() command, as we did with arrays in the preceding section. But you may want to sort the keys numerically or sort the hash by its values. To do this requires a little more work. You can define a subroutine to compare the keys or values. (See subroutines in Chapter 11). The subroutine will be called by the built-in sort() function. It will be sent a list of keys or values to be compared. The comparison is either an ASCII (alphabetic) or a numeric comparison, depending upon the operator used. The "cmp" operator is used for comparing strings, and the "<=>" operator is used for comparing numbers. The reserved global scalars $a, and $b are used in the subroutine to hold the values as they are being compared. The names of these scalars cannot be changed.
Sort Hash by Keys in Ascending Order
To perform an Ascii or alphabetic sort on the keys in a hash is relatively easy. The sort() function is given a list of keys and returns them sorted in ascending order. A foreach loop is used to loop through the hash one key at a time. See Example 5.56.
Example 5.56.
(In Script)
1 %wins = (
"Portland Panthers" => 10,
"Sunnyvale Sluggers" => 12,
"Chico Wildcats" => 5,
"Stevensville Tigers" => 6,
"Lewiston Blazers" => 11,
"Danville Terriors" => 8,
);
print "\n\tSort Teams in Ascending Order:\n\n";
2 foreach $key( sort(keys %wins)) {
3 printf "\t% -20s%5d\n", $key, $wins{$key};
}
(Output)
Sort Teams in Ascending Order:
Chico Wildcats 5
Danville Terriors 8
Lewiston Blazers 11
Portland Panthers 10
Stevensville Tigers 6
Sunnyvale Sluggers 12
A hash called %wins is assigned key/value pairs. The foreach loop will be used to iterate through each of the elements in the hash. The foreach receives an alphabetically sorted list as output from the sort() function. The sort() function gets its list from the built-in keys function, which returns a list of all the keys in a hash. The printf() function formats and prints the keys and sorted values.
|
Sort Hash by Keys in Reverse Order
To sort a hash by keys alphabetically and in descending order, just add the built-in reverse() function to the previous example. The foreach loop is used to get each key from the hash, one at a time, after the reversed sort.
Example 5.57.
1 %wins = (
"Portland Panthers" => 10,
"Sunnyvale Sluggers" => 12,
"Chico Wildcats" => 5,
"Stevensville Tigers" => 6,
"Lewiston Blazers" => 11,
"Danville Terriors" => 8,
);
print "\n\tSort Teams in Descending/Reverse Order:\n\n";
2 foreach $key (reverse sort(keys %wins)) {
3 printf "\t% -20s%5d\n", $key, $wins{$key};
}
(Output)
Sort Teams in Descending/Reverse Order:
Sunnyvale Sluggers 12
Stevensville Tigers 6
Portland Panthers 10
Lewiston Blazers 11
Danville Terriors 8
Chico Wildcats 5
A hash called %wins is assigned key/value pairs. The foreach loop will be used to iterate through each of the elements in the hash. The reverse() function takes the alphabetically sorted list returned from the sort() function and reverses it. This reversed list is used by the foreach function to extract each key and value from the hash %wins. The printf() function formats and prints the keys and sorted values.
|
Sort Hash by Keys Numerically
A user-defined subroutine is used to sort a hash by keys numerically. In the subroutine, Perl's special $a and $b variables are used to hold the value being compared with the appropriate operator. For numeric comparison, the <=> operator is used, and for string comparison, the "cmp" operator is used. The sort() function will send a list of keys to the user-defined subroutine. The sorted list is returned.
Example 5.58.
Code View: 1 sub desc_sort_subject {
2 $b <=> $a; # Numeric sort descending
}
3 sub asc_sort_subject{
4 $a <=> $b; # Numeric sort ascending
}
5 %courses = (
"101" => "Intro to Computer Science",
"221" => "Linguistics",
"300" => "Astronomy",
"102" => "Perl",
"103" => "PHP",
"200" => "Language arts",
);
print "\n\tCourses in Ascending Numeric Order:\n";
6 foreach $key (sort asc_sort_subject(keys(%courses))) {
7 printf "\t%-5d%s\n", $key, $courses{"$key"};
}
print "\n\tCourses in Descending Numeric Order:\n";
foreach $key (sort desc_sort_subject(keys(%courses))) {
printf "\t%-5d%s\n", $key, $courses{"$key"};
}
(Output)
Courses in Ascending Numeric Order:
101 Intro to Computer Science
102 Perl
103 PHP
200 Language arts
221 Linguistics
300 Astronomy
Courses in Descending Numeric Order:
300 Astronomy
221 Linguistics
200 Language arts
103 PHP
102 Perl
101 Intro to Computer Science
This is a user-defined subroutine called desc_sort_sub ject(). When its name is given to the sort() function, this function will be used to compare the keys passed to it. It will sort the keys numerically. The special Perl variables $a and $b are used to compare the values of the keys from the hash called $courses. The <=> operator is a numeric comparison operator that will compare each of the keys to be sorted as numbers. In the previous examples, we sorted the keys alphabetically. Since $b precedes $a, the sort is descending. This is also a user-defined subroutine called asc_sort_subject(). This function is identical to the previous function on line 1, except it will sort the keys of the hash in ascending numeric order rather than descending. In this function, the special variables $a and $b have been reversed, causing the sort after the comparison to be in ascending order. The hash called %courses is defined with key/value pairs. The foreach loop will be used to iterate through each of the elements in the hash. It receives its list from the output of the sort() command. The printf() function formats and prints the keys and sorted values.
|
Numerically Sort a Hash by Values in Ascending Order
To sort a hash by its values, a user-defined function is also defined. The values of the hash are compared by the special variables $a and $b. If $a is on the left-hand side of the comparison operator, the sort is in ascending order, and if $b is on the left-hand side, then the sort is in descending order. The <=> operator compares its operands numerically.
Example 5.59.
(In Script)
1 sub asc_sort_wins {
2 $wins{$a} <=> $wins{$b};
}
3 %wins = (
"Portland Panthers" => 10,
"Sunnyvale Sluggers" => 12,
"Chico Wildcats" => 5,
"Stevensville Tigers" => 6,
"Lewiston Blazers" => 11,
"Danville Terriors" => 8,
);
print "\n\tWins in Ascending Numeric Order:\n\n";
4 foreach $key (sort asc_sort_wins(keys(%wins))) {
5 printf "\t% -20s%5d\n", $key, $wins{$key};
}
(Output)
Wins in Ascending Numeric Order:
Chico Wildcats 5
Stevensville Tigers 6
Danville Terriors 8
Portland Panthers 10
Lewiston Blazers 11
Sunnyvale Sluggers 12
This is a user-defined subroutine called asc_sort_wins(). When its name is given to the sort() function, this function will be used to compare the hash values passed to it. It will sort the values by value, numerically. The special Perl variables $a and $b are used to compare the values of the hash called $wins. The <=> operator is a numeric comparison operator that will compare each of the values to be sorted. To compare strings, the "cmp" operator is used. The hash called %wins is assigned key/value pairs. The foreach loop iterates through each of the elements in the hash. It receives its list from the output of the sort() command. The printf() function formats and prints the keys and sorted values.
|
Numerically Sort a Hash by Values in Descending Order
To sort a hash numerically and in descending order by its values, a user-defined function is defined as in the previous example. However, this time the $b variable is on the left-hand side of the <=> numeric operator, and the $a variable is on the right-hand side. This causes the sort() function to sort in descending order.
Example 5.60.
Code View: (In Script)
# Sorting a Hash by Value in Descending Order
1 sub desc_sort_wins {
2 $wins{$b} <=> $wins{$a}; # Reverse $a and $b
}
3 %wins = (
"Portland Panthers" => 10,
"Sunnyvale Sluggers" => 12,
"Chico Wildcats" => 5,
"Stevensville Tigers" => 6,
"Lewiston Blazers" => 11,
"Danville Terriors" => 8,
);
print "\n\tWins in Descending Numeric Order:\n\n";
4 foreach $key (sort desc_sort_wins(keys(%wins))) {
5 printf "\t% -20s%5d\n", $key, $wins{$key};
}
(Output)
Wins in Descending Numeric Order:
Sunnyvale Sluggers 12
Lewiston Blazers 11
Portland Panthers 10
Danville Terriors 8
Stevensville Tigers 6
Chico Wildcats 5
This is a user-defined subroutine called desc_sort_wins(). When its name is given to the sort() function, this function will be used to compare the hash values passed to it. It will sort the values by value, numerically but in descending order. The special Perl variables $a and $b are used to compare the values of the hash called $wins. The position of $a and $b determines whether the sort is in ascending or descending order. If $a is on the left-hand side of the <=> operator, the sort is a numeric ascending sort; if $b is on the left-hand side of the <=> operator, the sort is descending. To compare strings, the "cmp" operator is used. The hash called %wins is assigned key/value pairs. The foreach loop will be used to iterate through each of the elements in the hash. It receives its list from the output of the sort() command. The printf() function formats and prints the keys and sorted values.
|
5.5.5. The delete Function
The delete function deletes a value from a hash. The deleted value is returned if successful.
Example 5.61.
(In Script)
#!/usr/bin/perl
1 %employees=(
"Nightwatchman" => "Joe Blow",
"Janitor" => "Teddy Plunger",
"Clerk" => "Sally Olivetti",
);
2 $layoff=delete $employees{"Janitor"};
print "We had to let $layoff go.\n";
print "Our remaining staff includes: ";
print "\n";
while(($key, $value)=each(%employees)){
print "$key: $value\n";
}
(Output)
We had to let Teddy Plunger go.
Our remaining staff includes:
Nightwatchman: Joe Blow
Clerk: Sally Olivetti
A hash is defined with three key/value pairs. The delete function deletes an element from the specified hash by specifying the key. Janitor is the key. Both key and value are removed. The hash value associated with the key Janitor is removed and returned. The value Teddy Plunger is returned and assigned to the scalar $layoff.
|
|
5.5.6. The exists Function
The exists function returns true if a hash key (or array index) has been defined, and false if not.
Example 5.62.
#!/usr/bin/perl
1 %employees=( "Nightwatchman" => "Joe Blow",
"Janitor" => "Teddy Plunger",
"Clerk" => "Sally Olivetti",
);
2 print "The Nightwatchman exists.\n" if exists
$employees{"Nightwatchman"};
3 print "The Clerk exists.\n" if exists $employees{"Clerk"};
4 print "The Boss does not exist.\n" if not exists
$employees{"Boss"};
(Output)
2 The Nightwatchman exists.
3 The Clerk exists.
4 The Boss does not exist.
A hash is defined with three key/value pairs. If a key "Nightwatchman" has been defined, the exists function returns true. If a key "Clerk" has been defined, the exists function returns true. If the key "Clerk" does not exist, the return value of the exists function is reversed.
|
|