
I find these kinds of data structures are hard to get a handle on, so I decided to use some data that I was familiar with. Here is a very small collection of some of my music collection.
This particular structure is a hash of hashes.
Paste this into a new Perl script:
#! /usr/bin/perl
use strict;
use warnings;
my ($artist,$cd,$tracknum,$track,%music);
my $Andx=1; #artist index
my $Cndx=1; #CD index
%music = (
"Aural Float" => {
"Freefloat" => {
"01" => "Perspectives",
"02" => "Freefloat",
"03" => "Switchin' The Wave Of Thought",
"04" => "Soulsearching",
"05" => "Travelogue",
"06" => "At The Crossroads",
"07" => "New Frontiers",
"08" => "Zwei G",
"09" => "Session 5",
"10" => "AF Study II",
"11" => "Switchin' The Wave Of Thought (Reprise)",
},
"Beautiful Someday" => {
"01" => "How Deep",
"02" => "Dreamer's Dream",
"03" => "Him & Her",
"04" => "Interlude I",
"05" => "Beautiful Someday",
"06" => "Gone Forever",
"07" => "Still Here",
"08" => "Simplicity",
"09" => "Interlude II",
"10" => "I Adore You",
"11" => "Männerwirtschaft",
"12" => "Be As You Are",
"13" => "Interlude III",
"14" => "Life In Dub",
},
},
);
In this example, 'Aural Float' is a key to two values: 'Freefloat' and 'Beautiful Someday'.
They in turn are each keys to a hash of track numbers, which are keys to track names (values).
To print a list (sorted by artist and CD) ...
foreach $artist (sort keys (%music)) {
print "$Andx $artist\n";
$Andx++;
foreach $cd (sort keys $music{$artist}) {
print "\t$Cndx $cd\n";
$Cndx++;
foreach $tracknum (sort keys $music{$artist}{$cd}) {
print "\t\t$tracknum $music{$artist}{$cd}{$tracknum}\n";
}
}
}

Very nice, we've even added a counter for artist, and their CDs.
But can you search for something?
print "Do you have anything by 'Aural Float'?\n";
if (exists($music{"Aural Float"})) {
print "Yes I do:\n" ;
for $cd (sort keys $music{'Aural Float'} ) {
print "\t $cd\n";
$cdSaved=$cd;
}
}

Great ... "What are the tracks on 'Freefloat'?"
$cd = "Freefloat";
print "What are the tracks on '$cd'?\n";
foreach $artist (keys %music) {
foreach $tracknum (sort keys $music{$artist}{$cd}) {
print "$tracknum $music{$artist}{$cd}{$tracknum}\n";
}
}

Finally, can you search for a track by an artist?
This one is a little tricky, because now we need to search for a value not a key. We can't use exists for this, since that only looks for keys.
my $query = "Interlude II"; # comment this line & uncomment next line to try 'unfound'
#my $query = "0asdf09a8dsI"; # uncomment this line & comment previous line to try 'unfound'
$artist = "Aural Float";
my $found;
print "Do you have '$query' by '$artist'?\n";
foreach $cd (keys $music{$artist}) {
foreach $tracknum (keys $music{$artist}{$cd}) {
if ($query eq $music{$artist}{$cd}{$tracknum}) {
# use 'eq' instead of '=~' to match exact track
$found=1;
print "Yes, it's on '$cd', track $tracknum\n" if ($found==1);
}
else {
$found=0;
}
}
}
print "Not found.\n" if (! $found);
We've used variables to hold our search item and artist - they can be used just like a literal string in the search code.
We've also used eq instead of the match operator =~ because there are other tracks that are similar to our query, but only 1 exact match.
![]()
![]()
I hope with these examples you can begin to see the power of hashes.
Next, what else can we do with hashes?