Prerequisite: Hashes-Basics
Introduction
Beyond the normal constraints of the hashes, we can also create complex structures made up of combinations of two. These are nested or complex structures and they can be used to model complex data in an easy-to-use
format.
Among all of the Perl’s nested structures, a Multidimensional hash or Hash of Hashes is the most flexible. It’s like building up a record that itself contains a group of other records.
The format for creating a hash of hashes is similar to that for array of arrays. Simply, instead of assigning the values to the primary keys in a normal hash, assign a whole hash containing secondary keys and their respective values to the primary keys of the outer hash.
Syntax:
my %hash = (primary_key => {secondary_key => {sub_sec_key => {…}}});
Example:
Following example shows a hash of hashes that describes a company organization. The primary keys are the departments, and the nested keys are the employee names. The values then contain the corresponding employee’s job title.
use strict;
use warnings;
use Data::Dumper qw(Dumper) ;
my %company = ( 'Sales' => {
'Brown' => 'Manager' ,
'Smith' => 'Salesman' ,
'Albert' => 'Salesman' ,
},
'Marketing' => {
'Penfold' => 'Designer' ,
'Evans' => 'Tea-person' ,
'Jurgens' => 'Manager' ,
},
'Production' => {
'Cotton' => 'Paste-up' ,
'Ridgeway' => 'Manager' ,
'Web' => 'Developer' ,
},
);
print Dumper(\ %company );
|
Output:
$VAR1 = {
'Marketing' => {
'Evans' => 'Tea-person',
'Jurgens' => 'Manager',
'Penfold' => 'Designer'
},
'Sales' => {
'Smith' => 'Salesman',
'Albert' => 'Salesman',
'Brown' => 'Manager'
},
'Production' => {
'Ridgeway' => 'Manager',
'Web' => 'Developer',
'Cotton' => 'Paste-up'
}
};
In above example, the input of the Dumper function is a reference to a data structure and thus we put a back-slash (\) in front of %company.
Note: The order of the keys is random as hashes do not keep them in any specific order.
Some other operations:
- To add another anonymous member to the existing hash:
Syntax:
$company{‘new_key’} = {‘sub_key1’ => value1,
‘sub_key2’ => value2,
‘sub_key3’ => value3
};
- Access particular value:
Syntax:
print $company{“Production”}{“Web”}; # will output “Developer”
- Set value of a particular key:
Syntax:
$company{$Production}->{“Web”} = Senior Developer ; # changes Web to Senior Developer
Traversing Multidimensional Hashes
To traverse through the multidimensional hash or to go through each value in a hash, simply loop through the keys of the outer hash and then loop through the keys of the inner hashes.
For N-dimension hash, N nested or embedded loops are required to traverse through the complete hash. Both For and While loops can be used to loop over to the hash.
Syntax:
for $key ( keys %hash )
{
print "$key: \n" ;
for $ele ( keys %{ $hash { $key }})
{
print " $ele: " . $hash { $key }->{ $ele } . "\n" ;
}
}
|
For large-sized multidimensional hashes, it may be slightly faster to retrieve both keys and the values at the same time using each keyword.
Syntax:
while (( $key , $ele ) = each %hash )
{
print "$key: \n" ;
while (( $ele , $sub_ele ) = each % $ele )
{
print " $ele = $sub_ele " ;
}
print "\n" ;
}
|
Following example illustrates the traversing through a multidimensional hash using For
and while
loops:
Example:
use strict;
use warnings;
use Data::Dumper qw(Dumper) ;
my %company = ( 'Sales' => {
'Brown' => 'Manager' ,
'Smith' => 'Salesman' ,
'Albert' => 'Salesman' ,
},
'Marketing' => {
'Penfold' => 'Designer' ,
'Evans' => 'Tea-person' ,
'Jurgens' => 'Manager' ,
},
'Production' => {
'Cotton' => 'Paste-up' ,
'Ridgeway' => 'Manager' ,
'Web' => 'Developer' ,
},
);
print "Traversing hash using For loop: " . "\n" ;
print "\n" ;
for my $key ( keys %company )
{
print "$key: \n" ;
for my $ele ( keys %{ $company { $key }})
{
print " $ele: " . $company { $key }->{ $ele } . "\n" ;
}
}
print "\nTraversing hash using while" .
"loop using each keyword: " . "\n" ;
print "\n" ;
while (( my $key , my $ele ) = each %company )
{
print "$key: \n" ;
while (( my $ele , my $sub_ele ) = each % $ele )
{
print " $ele = $sub_ele " ;
}
print "\n" ;
}
|
Output:
Traversing hash by For loop.
Marketing:
Evans: Tea-person
Jurgens: Manager
Penfold: Designer
Sales:
Brown: Manager
Albert: Salesman
Smith: Salesman
Production:
Cotton: Paste-up
Web: Developer
Ridgeway: Manager
Traversing hash using while loop with each keyword.
Marketing:
Evans=Tea-person Jurgens=Manager Penfold=Designer
Sales:
Brown=Manager Albert=Salesman Smith=Salesman
Production:
Cotton=Paste-up Web=Developer Ridgeway=Manager
Check for key existence in Multidimensional Hashes
Many times when working with a Perl hash, we need to know if a certain key already exists in the hash. Given a hash, one can check the existence of a particular key by using the exists
keyword.
In a multidimensional hash like %company used in above examples, one has to use the keyword exists
up until the depth level of the key being checked for existence, has been reached.
Syntax:
if (exists($hash{key})) {
if (exists($hash{key}{sub_key})) {
….
}
}
One should also be careful using the nth-level construct without trying the (n-1)th-level first as that might trigger unwanted autovivification
Example:
Here’s a simple example that demonstrates the Perl exists
hash function. In this Perl script, we’ll first create a simple Perl hash, and then we’ll use the exists
function to see if the hash key named ‘Albert’ exists in the hash.
use strict;
use warnings;
my %company = ( 'Sales' => {
'Brown' => 'Manager' ,
'Smith' => 'Salesman' ,
'Albert' => 'Salesman' ,
},
'Marketing' => {
'Penfold' => 'Designer' ,
'Evans' => 'Tea-person' ,
'Jurgens' => 'Manager' ,
},
'Production' => {
'Cotton' => 'Paste-up' ,
'Ridgeway' => 'Manager' ,
'Web' => 'Developer' ,
},
);
if ( exists $company { "Sales" })
{
print "Sales department exists.\n" ;
if ( exists $company { "Sales" }{ "Albert" })
{
print "Albert is " . $company { "Sales" }{ "Albert" } .
" of Sales department . \n" ;
}
else
{
print "Albert is not a member of Sales department.\n" ;
}
}
else
{
print "Sales department do not exists.\n" ;
}
|
Output:
Sales department exists.
Albert is Salesman of Sales department.
Whether you're preparing for your first job interview or aiming to upskill in this ever-evolving tech landscape,
GeeksforGeeks Courses are your key to success. We provide top-quality content at affordable prices, all geared towards accelerating your growth in a time-bound manner. Join the millions we've already empowered, and we're here to do the same for you. Don't miss out -
check it out now!
Last Updated :
27 Jun, 2019
Like Article
Save Article