Previous Page Next Page

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").

Format

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

Explanation

  1. The hash %weekday is assigned keys and values.

  2. 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.

  3. 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.

Format

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

Explanation

  1. The hash %weekday is assigned keys and values.

  2. 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.

Format

each(ASSOC_ARRAY)

Example 5.55.

(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

					  

Explanation

  1. The hash %weekday is assigned keys and values.

  2. The each function returns each key and its associated value of the %weekday hash. They are assigned to the scalars $key and $value, respectively.

  3. 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

Explanation

  1. A hash called %wins is assigned key/value pairs.

  2. 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.

  3. 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

Explanation

  1. A hash called %wins is assigned key/value pairs.

  2. 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.

  3. 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.

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

					  

Explanation

  1. 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.

  2. 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.

  3. 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.

  4. In this function, the special variables $a and $b have been reversed, causing the sort after the comparison to be in ascending order.

  5. The hash called %courses is defined with key/value pairs.

  6. 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.

  7. 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

					  

Explanation

  1. 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.

  2. 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.

  3. The hash called %wins is assigned key/value pairs.

  4. The foreach loop iterates through each of the elements in the hash. It receives its list from the output of the sort() command.

  5. 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.

    (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

					  

Explanation

  1. 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.

  2. 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.

  3. The hash called %wins is assigned key/value pairs.

  4. 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.

  5. 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.[8]

[8] If a value in an %ENV hash is deleted, the environment is changed. (See "The %ENV Hash" on page 129.)

Format

delete $ASSOC_ARRAY{KEY}

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

Explanation

  1. A hash is defined with three key/value pairs.

  2. The delete function deletes an element from the specified hash by specifying the key. Janitor is the key. Both key and value are removed.

  3. 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.

Format

exists $ASSOC_ARRAY{KEY}

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.

Explanation

  1. A hash is defined with three key/value pairs.

  2. If a key "Nightwatchman" has been defined, the exists function returns true.

  3. If a key "Clerk" has been defined, the exists function returns true.

  4. If the key "Clerk" does not exist, the return value of the exists function is reversed.


Previous Page Next Page