Perl | Multidimensional Hashes
- Prerequisite: Hashes-Basics
- 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
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.
# !/usr/bin/perl # Perl program to demonstrate # Multidimensional hash use strict; use warnings; use Data::Dumper qw(Dumper) ; # Creating a 2D hash 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 the List print Dumper(\ %company ); |
$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:
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:
# !/usr/bin/perl # Perl program to demonstrate # Traversing of # Multidimensional hash 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" ; # traversing hash using for loop 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" ; # traversing hash using each keyword # and while loop while (( my $key , my $ele ) = each %company ) { print "$key: \n" ; while (( my $ele , my $sub_ele ) = each % $ele ) { print " $ele = $sub_ele " ; } print "\n" ; } |
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.
# !/usr/bin/perl # Perl program to check for # existence of a key in a # Multidimensional 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' , }, ); # Check for key existence 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" ; } |
Sales department exists. Albert is Salesman of Sales department.
Please Login to comment...