Advanced Data Structures, part 2


Arrays of arrays

You can create a N-dimensional matrix in perl with arrays of arrays of arrays .... Here the principle will be shown with a 2-dimensional matrix, which is an array of references to anonymous arrays. A 3-dimensional matrix is an array of references of anonymous arrays of references, that refer to anonymous arrays - get the picture?
# Simple assignment of an array of arrays
my @AoA = ([1,2,3], ['John', 'Joe', 'Ib'], ['Eat', 2]);
print $AoA[1][2]; # prints Ib

# Suppose you want to read a matrix in from a file 
while (defined (my $line = <IN>)) {
   my @tmp = split(' ', $line); 
   push(@AoA, [@tmp]); } # Add anonumous array (row) to @AoA

# Suppose you want to add a column to a matrix
for (my $i = 0; $i <= $#AoA; $i++) {
   push(@{$AoA[$i]}, "Some value"); }

# You could also just assign the values
for (my $x = 0; $x <= 10; $x++) {
   for (my $y = 0; $y <= 10; $y++) {
      $AoA[$x][$y] = &func($x, $y); } }

# Printing/accessing the AoA
for (my $x = 0; $x <= $#AoA; $x++) {
   for (my $y = 0; $y <= $#{$AoA[$x]}; $y++) {
      print "At X=$x, Y=$y is ", $AoA[$x][$y], "\n"; } }

# A common mistake
print @AoA; # Simply prints a list of array references

Hashes of arrays

# Simple assignment
%HoA = ('Numbers' => [1, 2, 3], 'Names' => ['John', 'Joe', 'Ib']);

# Adding an array to the hash
my @tmp = split(' ', $line);
$HoA{'NewKey'} = [@tmp];

# Appending a new element to one the the arrays
push(@{$HoA{'NewKey'}}, 'SomeValue');

# Two ways of accessing the structure
print $HoA{'Numbers'}[1]; # prints 2
print $HoA{'Names'}->[1]; # prints Joe

Arrays of hashes

# Simple assignment
@AoH = ({'key1' => 'value1', 'key2' => 'value2},
        {'newhashkey1' => 'value1', 'key2' => 'value2},
        {'anotherhashkey1' => 'value1', 'key2' => 'value2});

# Adding anonymous hash to the array
push(@AoH, {'key' => 'val', 'xkey' => 'xval'});
$AoH[2] = {'key' => 'val', 'xkey' => 'xval'};

# Adding single key/value pair in one of the hashes
$AoH[1]{'NewKey'} = 'NewValue';

# Accessing the structure
for (my $i = 0; $i <= $#AoH; $i++) {
   foreach my $key (keys %{$AoH[$i]}) {
      print $AoH[$i]{$key}, "\n"; } }

Hashes of hashes

This is the most flexible (and unordered) datastructure in perl.
# Simple assignment
%HoH = ('Masterkey1' => {'Key1' => 'Value1', 'Key2' => 'Value2' }, 
        'Masterkey2' => {'Key1' => 'Value1', 'Key2again' => 'Value2again' } );

# Adding an anonymous hash to the hash
$HoH{'NewMasterKey'} = {'NewKey1' => 'NewValue1', 'NewKey2' => 'NewValue2'}; 

# Or if you have a hash you want to add
$HoH{'NewMasterKey'} = { %MyOldHash };

# Adding a key/value pair in the "second" level. Autovivification trap.
$HoH{'MasterKey1'}{'NewKey'} = 'NewValue';

# Printing/using a single value
print $HoH{'MasterKey1'}{'Key1'};

# Accessing the structure
foreach my $masterkey (keys %HoH) {
   print "First level: $masterkey\n";
   foreach my $key (keys %{$HoH{$masterkey}}) {
      print "$key => $HoH{$masterkey}{$key}\n"; } }

This page was last updated         by Peter Wad Sackett, pws@cbs.dtu.dk