Perl Hashes

Perl Hashes Menu:

Defining hashes
One-dimensional hashes
    Copy a hash
    Create or initialize a hash
    Empty or clear a hash
    Extract slices from a hash
    Find out if a hash variable contains references
    Get the size of a hash
    Insert or add new items into a hash
    Loop or iterate through a hash
    Print a hash
    Remove a key from a hash
    Sort or order a hash
    Reverse a hash
    Find the length in bytes of a hash of hashes

Defining hashes

After scalars and arrays, Perl hashes (or Perl associative arrays) is the third native built-in data type of Perl language. By scalar we mean the simplest Perl data type which was designed to hold only one thing like a number, a string or a reference. The array is a more complex data type which is meant to hold collections of scalars. For each of these built-in data type variables, Perl language has a special symbol which precedes the variable name: $ for scalar, @ for array and % for hash.

Perl Hashes (associative arrays) are most like arrays but there are some significant differences, too. An array has a number of elements (scalars) and to access one particular element we use the index (or subscript) of that element, where the first element has the index 0, the next one 1, and so on. A hash contains a number of scalars, too. But in this case an element of the structure represents a pair of two parts – a key and a value. Whenever we refer to an element of a Perl hash structure, we mean a pair which links a value to a key. We have access at the elements of a hash variable by a scalar key and not by an index (like in arrays).

In the Perl language, the hash structure is based upon a Perl hash table that associates keys with values. In order to retrieve an element of a hash variable, you must supply a key and find the corresponding value. The keys are unique but for different keys you can have identical values.

back to top

One-dimensional hashes

By one-dimensional Perl hashes or simple hashes we generally mean hashes whose elements are not references to other Perl structures (arrays or hashes). See %ages and %members hashes shown below for an example:

%ages = ("John", 43, "Paul", 25, "Marie", 22);
%members = (John => "father", Paul => "son", 
                        Marie => "daughter");

back to top

Copy a hash

%destHash = %sourceHash;  # copy a hash
$destHasRef = $sourceHashRef;  # copy a hash ref

This is a shallow method to copy Perl hashes, and works well when we speak about one–dimensional hashes, with no references to other structures.

back to top

Create or initialize a hash

Perl hashes are structures and you do not need to allocate structures or other variables in Perl. The first time you use a hash type variable in your code, that variable will be automatically created. Please look at the following code:

%ages = ("John", 43, "Paul", 25, "Marie", 22);
%members = (John => "father", Paul => "son", 
                      Marie => "daughter");
$agesRef = \%ages;
print $$agesRef{Marie}; #prints 22 

In the above example, we used two ways to create/initialize a hash variable. In the first line we initialized the %ages hash variable with a list composed by pairing of keys and values, separated by commas. But Perl has a special "comma-arrow" (=>) operator that we used to initialize the %members hash variable in the second line of code. The left side of the comma-arrow operator is expected to be a simple string and therefore it is not necessary to be quoted.

The third line shows you how to define a hash reference in Perl. You can dereference Perl hashes using the notation %$hashRef. If you want to get a certain hash value, you can dereference it by using the notation $$hashRef{key} – the fourth line of the above snippet code shows you how to do that.

I’ll show you below the Perl hash table for both the %ages and %members hash variables.


key value
John 43
Paul 25
Marie 22


key value
John father
Paul son
Marie daughter

back to top

Empty or clear a hash

In order to initialize Perl hashes to an empty list, you can use the code line:

%hash = ();

After the initialization, all the elements of the hash will be deleted.

back to top

Extract slices from a hash

Perl lets you extract slices from Perl hashes. Please look at the following code:

# define a hash
%cds = ("Dr. Hook"         => "Sylvias Mother", 
            "Rod Stewart"    => "Maggie May", 
            "Andrea Bocelli"  => "Romanza",
            "Kenny Rogers"  => "For the good times",
            "Bee Gees"        => "One night only",
            "Bonnie Tyler"    => "Hide your heart"); 

# we used the @ prefix because the return value
# represents a list
# we need to supply the keys for which we wanted 
# to extract the values 
@slice = @cds{"Dr. Hook","Kenny Rogers","Bee Gees"}; 
# we used the join function to print each string
# on a new line 
print join("\n", @slice);

Running the code it will produce the output:

Sylvias Mother
For the good times
One night only

back to top

Find out if a hash variable contains references

An easy way to find out if a variable is a simple string or number, or a reference to an array or a hash or something else, is to use the ref function. The ref function has the syntax form:

ref EXPR

If EXPR is not specified, $_ will be used. This function returns an empty string if the EXPR/$_ is not a reference, and a string (the type of reference) otherwise. Look at the code below to see how it works:

# define some simple variables
# we can use the same name – colors for different things
$colors = "darkblue";
@colors = qw(blue, red, yellow, brown);
%colors = (c1 => "blue", c2 => "green", c3 => "yellow");

# define a hash with references
%moreColors = (1 => "white", 2 => \$colors, 
                      3 => \@colors, 4 => \%colors);

# loop through %moreColors hash to find out the references
foreach $key (keys %moreColors)
  if (ref $moreColors{$key} eq "SCALAR") {
    print "$key: SCALAR\n";
  } elsif (ref $moreColors{$key} eq "ARRAY") {
    print "$key: ARRAY\n";
  } elsif (ref $moreColors{$key} eq "HASH") {
    print "$key: HASH\n";
  } elsif (ref $moreColors{$key} eq "") {
    print "$key: NO REFERENCE\n";

And here is what you get as output if you run the code:


Do you see the order (4 1 3 2) in which the keys were printed? Perl doesn’t care about the sequential order (1 2 3 4) in which I initialized %moreColors hash! Remember, if you want to print Perl hashes in some order, you must sort the hashes yourself. (see "Sort or order a hash").

back to top

Get the size of a hash

If you want to find out the number of elements of Perl hashes - or the Perl hash size, you can use the scalar context of its keys, like in the following example:

%time = (hour => 12, min =>25, sec => 32, msec =>75);
$size = scalar keys %time;   # explicit scalar context - or
$size = keys %time;   # implicit scalar context - or

$timeRef = \%time;    # using a reference
$size = keys %$timeRef;   

print "Hash size: $size\n";  # prints Hash size: 4

back to top

Insert or add new items into a hash

To insert a new (key, value) pair in a hash structure, you can use the syntax form:

$hash{"key"} = "value";

If hash doesn’t exist, it will be created automatically by Perl. Please have a look at the following code to see some examples:

%ages = ("John", 43, "Paul", 25, "Marie", 22);
$ages{"Anne"} = 22;
$ages{"Paul"} = 24;
$ages{"Marie"} = 24 unless exists $ages{"Marie"} ;
$ages{"George"} = 51 unless exists $ages{"George"} ;
print %ages, "\n";

In the first line I initialized the %ages hash. In the second and the third lines I inserted two elements in the hash variable. Please beware that the key "Paul" already exists and its associated value was over-written with the new value (24). The next two lines insert only new items into the %ages hash – I used unless exists to check up if a certain key exists in a hash before adding it. Please note the dollar sign in $ages{"Marie"} and remember that a single element of a hash is a scalar. The output of this code is shown below:


Please note that the hash is not ordered and you couldn’t expect at any order when you display its elements. Because Perl hashes are not ordered, I preferred to use the insert/add verb instead of append (the end of a hash has not particular meaning).

back to top

Loop or iterate through a hash

To loop or iterate through Perl hashes, you can use each function. This function iterates or loops through the (key, value) pairs of a hash, each (key, value) pair being returned as a two-element list. See the example below to find out how it works:

%phoneNumbers = ("Anne", "432566", "Paul", "231275", "Marie", 
while (($key, $value) = each %phoneNumbers)
  print "$key has the phone number $phoneNumbers{$key}\n";

The code shown above will extract the keys and values from the %phoneNumbers hash and it will display as output:

Anne has the phone number 432566
Paul has the phone number 231275
Marie has the phone number 299302

(see Print a hash for another way to loop through Perl hashes)

back to top

Print a hash

I’ll show you how to print the keys/values of Perl hashes. I’ll assign some elements to a hash structure (by using the syntax: $hash{$key}=value;), then I’ll iterate through the elements of the hash structure in order to print its keys/values pairs, as you see in the following snippet code:

# I’ll create a new hash - %notebookPrices 
# by assigning some elements to it:


# the next loop prints the keys/values of the hash
foreach $key (keys %notebookPrices)
  print "Key: $key, Value: \$$notebookPrices{$key}\n";

After running this code, you’ll get the output:

Key: Acer, Value: $750
Key: Toshiba, Value: $650
Key: HP, Value: $550

Note that Perl does not have a default order for the elements of a hash.

back to top

Remove a key from a hash

If you want to remove a single hash (key, value) pair from Perl hashes, you can use the delete function, in one of the following syntax forms:

delete $hash{$key};
delete $hashRef->{$key};   # if you have a hash reference
delete $$hashRef{$key};    # if you have a hash reference

See the examples below about how to implement it:

%phoneNumbers = ("Anne", "408566", "Paul", "233375", "Marie", 
delete $phoneNumbers {"Paul"};
delete $phoneNumbers {"John"};
$phoneNumbersRef = \%phoneNumbers;
delete $$phoneNumbersRef{"Anne"};

#print the hash (keys, values)
foreach $key (keys % phoneNumbers)
  print "Key: $key, Value: $phoneNumbers{$key}\n";

The second line of this snippet code will have as effect the deletion of the "Paul" key from the %phoneNumbers hash. In the third line of the code we try to delete an inexistent key from the hash, the script will not return any error and the %phoneNumbers hash will remain unchanged.

As a note, to delete a key when you have a hash reference you can use either the notation $$hashRef{$key} or $hashRef->{$key}.

back to top

Sort or order a hash

Perl hashes are not ordered and you must not rely on the order in which you added the hash items – Perl uses internally its own way to store the items. You can sort a hash either by keys or values, using the sort function.

To sort a hash by key, you can use the following code lines:

# define a hash
%time = (hour => 12, min => 25, sec => 32, msec =>75);

# foreach loop
foreach $key (sort keys %time)
  print "$key: $time{$key}\n";

To sort a hash by value, in a descending order, you can use the following code:

# define a hash
%v = (v1 => 75, v2 => 251, v3 => 3, v4 => 12);

# sort by value and put the keys in an array 
@keys = sort {$v{$b} <=> $v{$a}} keys %v;

# loop through array to print the hash pairs ordered
foreach $key (@keys)
  print "$key: $v{$key}\n";

If you will run the code, it will produce the following output:

v2: 251
v1: 75
v4: 12
v3: 3

In the example above, our hash has numerical values so we used the numerical operator "<=> for the comparisons. If you want to sort the values lexically, you need to use the stringwise operator cmp instead of <=>.

back to top

Reverse a hash

Because a hash represents a list of (key, value) pairs, you can reverse such a list and after that each pair will become (value, key). We'll do this by using the reverse function. However, beware that the hash keys are unique and if the values of the source hash are not unique, some elements will be lost. I want to say that if you reverse again your resulting hash, it’s possible to obtain a shorter hash. Here is an example how you can implement it:

# define a hash
%cds = ("Dr. Hook"       => "Sylvias Mother", 
        "Andrea Bocelli" => "Romanza",
        "Bonnie Tyler"   => "Hide your heart"); 
%cdsReversed = reverse %cds;

# we’ll use Data::Dumper module to see 
# what it is in the hash
use Data::Dumper;
print Dumper(\%cdsReversed);

after running this code, we’ll get as output:

$VAR1 = {
          'Sylvias Mother' => 'Dr. Hook',
          'Hide your heart' => 'Bonnie Tyler',
          'Romanza' => 'Andrea Bocelli'

back to top

Find the length in bytes of a hash of hashes

If you want to see how to find the length in bytes of a hash of hashes (a hash that has as values references to other hashes), I suggest you to click here to watch this video on youtube.

back to top

If you want to download the Perl hashes script with all the above examples included, please click here: Script download

Table of Contents:

A Perl Script
Install Perl
Running Perl
Perl Data Types
Perl Variables
Perl Operators
Perl Lists
Perl Arrays
    Array Size
    Array Length
Perl Statements
    Perl if
    Perl unless
    Perl switch
    Perl while
    Perl do-while
    Perl until
    Perl do-until
    Perl for
    Perl foreach
Built-in Perl Functions
    Functions by Category
        String Functions
        Regular Expressions and Pattern Matching
        List Functions
        Array Functions
        Hash Functions
        Miscellaneous Functions
    Functions in alphabetical order

return to Perl Basics

Would you like to create your own website like this one?
Hit the Alarm Clock!

Site Build It!