6. Complex data structures - 2: Array of Hashes

An Array of Hashes (1) is similar to an Array of Arrays. The initialization of an array of hashes consists of an array variable (@AoH) to which a list is assigned. This list includes references to hashes separated by the curly brackets and separated by commas. Within the hashes the individual key/value pairs are defined. Recall that members of %name_hash are accessed by $name_hash{$key}

Recall how to construct an anonymous hash reference with curly braces {}:

$anon_hash_ref = {'key1' => 'value1', 'key2' => 'value2'};


6.1 Create

@AoH = ( # array of hashes; notice the open and close parenthesis: it's a real array!
{
'name' => 'Sebastian',
'age' => 40,
},
{
'name' => 'Daniel',
'age' => 38,
},
{
'name' => 'Florence',
'age' => 36,
}
);
Alternatively, you could use the following code for the construction of an AoH, but it is less clear.
@AoH = (
{ qw (name Sebastian age 40), },
{ qw (name Daniel age 38) },
{ qw (name Florence age 36) },
);
See also below.

You can extend the existing hashes by new key/value pairs:
$AoH[0]{children}=2;
$AoH[2]{children}=3;
6.1.1 Copy
@AoH_copy = @AoH;
6.1.2 Merge
@AoH_combi = (@AoH1, @AoH2);
6.1.3 Empty
@AoH_copy = ();


6.2 Access

6.2.1 Access hash members
$AoH[0]->{name}; # output: Sebastian
The age of 'Florence' is: $AoH[2]->{age}; # output: 36
6.2.2 Index last element
$AoH_length = scalar (@AoH);
$index_last_element = $AoH_length - 1;


6.3 Print

On printing:
print "AoH: $AoH[0]->{name}\n"; # output: Sebastian
print "AoH: $AoH[0]{name}\n"; # you may omit the arrow; output: Sebastian
The key order of hashes when printing the complete AoH seems to be random, also in case of the Array of Hashes. You've to use some sort mechanism in order to get expected results. In addition, sorting on a key would be nice. The following code -without for loops but with 'map'- is your friend!
@AoH_sorted = sort { $a->{age} <=> $b->{age} } @AoH; # sorting on 'age'; read Chapter 1.6 Sort of Part 2
print join "\n", map {"Name: " . $_->{name}."\nAge: " . $_->{age} . "\n"} @AoH_sorted;
Each element of the array is passed to the special variable '$_' when using 'map'!


6.4 Iterate

@AoH_copy = @AoH;foreach (@AoH_copy) {  print "[ name: $_->{name} age: $_->{age} ]\n";}


6.5 Operate

6.5.1 Add an element to a hash
The 'Push' function can be applied in adding a new hash to the Array of Hashes:
push (@AoH , {'name' => 'Kirsten', 'age' => 42});
which is equivalent to
push (@AoH,{'name','Kirsten','age', 42});
and to
push (@AoH, { qw(name Kirsten age 42) } );
Building the Array of Hashes, while reading formatted data from a text file, you could think of the following:
$input_str = "name=Kirsten age=42";
@member = split (/[\s=]+/, $input_str);
push (@AoH_copy,{ @member });
6.5.2 Remove an element of a hash with 'delete'
The 'Delete' function can be applied in removing an existing hash of the Array of Hashes. To remove the third hash reference:
delete (@AoH[2]) if (exists @AoH[2]);
To delete an array by key, use 'grep':
@AoH = grep { $_->{'name'} ne 'Daniel' } @AoH;
@AoH = grep { $_->{'age'} != 42 } @AoH;
6.5.3 Update a hash element
$AoH[0]->{name} = "SEBASTIAN";

Footnotes
(1) The common expression Arrays of Hashes is not correct! You should speak of Arrays of References of Hashes.