100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
Programming

Hashes of Arrays and Nested Structures

Learn how to build and traverse complex nested data structures in Perl using references, including hashes of arrays, arrays of hashes, and hashes of hashes.

Advanced PerlIntermediate9 min readJul 10, 2026
Analogies

Building Nested Data Structures

Perl's native hashes and arrays can only hold scalars directly, but references let you store a pointer to an entire array or hash as a hash value, which is how nested structures are built. A hash of arrays (HoA) uses an arrayref as each value, so %department can map a team name to a list of employee names stored at that key. This is the foundation of representing trees, records, and JSON-like data entirely in native Perl syntax without extra modules.

🏏

Cricket analogy: A scorer's ledger keyed by team name, where each entry is not a single number but an array of every batsman's individual score for that innings, like Australia mapping to [Warner, Smith, Labuschagne] with their runs.

Hash of Arrays

To build a hash of arrays you either assign an arrayref directly with square brackets, like $hoa{fruits} = ['apple', 'banana'], or you push onto an auto-created array using the arrow-dereference push @{ $hoa{key} }, $value. Perl's autovivification means that referencing $hoa{key} in an array context automatically creates an empty arrayref there the first time you use it, so you rarely need to pre-initialize each key before pushing. Accessing an individual element requires dereferencing with an arrow, such as $hoa{fruits}[0], while looping over all values in a bucket uses @{ $hoa{fruits} }.

🏏

Cricket analogy: When a new wicket falls, the scorer just calls push @{ $innings{wickets} }, $batsman without first checking whether the wickets array already exists, exactly like autovivification silently creating the array on first use.

perl
my %department;

push @{ $department{Engineering} }, 'Alice', 'Bob';
push @{ $department{Sales} },       'Carol';

for my $team (sort keys %department) {
    my @members = @{ $department{$team} };
    print "$team: @members\n";
}
# Engineering: Alice Bob
# Sales: Carol

Array of Hashes and Hash of Hashes

An array of hashes (AoH) is the natural shape for a list of records, such as rows returned from a CSV file or a database query, where each element is a hashref like { name => 'Alice', age => 30 }. You build it by pushing anonymous hashrefs onto an array: push @records, { name => $name, age => $age }. This is the idiom you will see constantly when processing tabular data, because it keeps each row's fields named rather than positional, which is far more readable than a plain array of arrays.

🏏

Cricket analogy: A match scorecard array where each element is a hashref like { batsman => 'Kohli', runs => 82, balls => 61 }, letting the scoring app push one structured record per dismissal rather than a bare list of numbers.

A hash of hashes (HoH) nests a hashref as a value instead of an array, which suits lookups by a unique key, such as %employees keyed by employee ID where each value is { name => ..., dept => ..., salary => ... }. You read a nested field with a chain of arrows, $employees{E123}{salary}, and Perl lets you drop the arrow between adjacent curly-brace or square-bracket subscripts, so $employees{E123}->{salary} and $employees{E123}{salary} are equivalent. This structure is ideal whenever you need O(1) lookup by ID rather than scanning a list, which an AoH would require.

🏏

Cricket analogy: A player registry hash keyed by jersey number where each value is a hashref { name => 'Bumrah', role => 'bowler', economy => 6.2 }, giving instant lookup instead of scanning a whole squad list.

Autovivification is powerful but can silently create unwanted empty hashrefs or arrayrefs. Merely checking if ($hash{key}{subkey}) creates $hash{key} as an empty hashref as a side effect. Use exists() carefully and consider Data::Dumper to inspect structures while debugging.

Traversing Nested Structures

Traversing nested structures means combining keys() or values() with dereferencing at each level, typically with nested for loops. For a hash of arrays, you loop over sorted keys() and then over the dereferenced array at each key; for a hash of hashes, you loop over the outer keys and then over the inner keys with keys %{ $hoh{$outer} }. Since Perl 5.24, postfix dereference syntax like $hoh{$outer}->%* or $hoa{$key}->@* is available and often reads more clearly than the older %{ $ref } sigil-wrapping style, especially for deeply nested chains.

🏏

Cricket analogy: A statistician loops through every team, then every player within that team's array, to compute the tournament's total run tally, the same two-level walk needed to sum values in a hash of arrays.

perl
my %hoh = (
    E123 => { name => 'Alice', dept => 'Eng',   salary => 95000 },
    E456 => { name => 'Bob',   dept => 'Sales', salary => 72000 },
);

for my $id (sort keys %hoh) {
    my $rec = $hoh{$id};
    print "$id: $rec->{name} ($rec->{dept}) \$$rec->{salary}\n";
}

# Postfix deref (Perl 5.24+)
for my $id (sort keys %hoh) {
    print "$id has ", scalar $hoh{$id}->%*, " fields\n";
}

Always use 'strict' and 'warnings' when working with nested structures — a typo in a key name won't raise an error, it will silently autovivify a new branch full of undef values, which is one of the most common sources of hard-to-find bugs in Perl scripts.

  • References let hash and array values point to other arrays or hashes, enabling arbitrary nesting.
  • A hash of arrays (HoA) maps keys to arrayrefs; build it with push @{ $hoa{key} }, $value.
  • An array of hashes (AoH) suits ordered records like CSV rows, each pushed as an anonymous hashref.
  • A hash of hashes (HoH) gives O(1) lookup by a unique key, unlike scanning an AoH.
  • Autovivification auto-creates intermediate structures on access, which is convenient but can mask typos.
  • Traverse nested structures with paired keys()/dereference loops, or Perl 5.24+ postfix deref syntax like ->@* and ->%*.
  • Always enable strict and warnings, since silent autovivification is a leading cause of nested-structure bugs.

Practice what you learned

Was this page helpful?

Topics covered

#Programming#PerlStudyNotes#HashesOfArraysAndNestedStructures#Hashes#Arrays#Nested#Structures#DataStructures#StudyNotes#SkillVeris