How can I store multiple values in a Perl hash table?

43,942

Solution 1

This is the standard way, as per perldoc perldsc.

~> more test.pl
%chums = ( "Allan" => {"Boss" => "George", "Status" => "Contractor"},
           "Bob" => {"Boss" => "Peter", "Status" => "Part-time"} );

print $chums{"Allan"}{"Boss"}."\n";
print $chums{"Bob"}{"Boss"}."\n";
print $chums{"Bob"}{"Status"}."\n";
$chums{"Bob"}{"Wife"} = "Pam";
print $chums{"Bob"}{"Wife"}."\n";

~> perl test.pl
George
Peter
Part-time
Pam

Solution 2

Hashes of hashes is what you're explicitly asking for. There is a tutorial style piece of documentation part of the Perl documentation which covers this: Data Structure Cookbook But maybe you should consider going object-oriented. This is sort of the stereotypical example for object oriented programming tutorials.

How about something like this:

#!/usr/bin/perl
package Employee;
use Moose;
has 'name' => ( is => 'rw', isa => 'Str' );

# should really use a Status class
has 'status' => ( is => 'rw', isa => 'Str' );

has 'superior' => (
  is      => 'rw',
  isa     => 'Employee',
  default => undef,
);

###############
package main;
use strict;
use warnings;

my %employees; # maybe use a class for this, too

$employees{George} = Employee->new(
  name   => 'George',
  status => 'Boss',
);

$employees{Allan} = Employee->new(
  name     => 'Allan',
  status   => 'Contractor',
  superior => $employees{George},
);

print $employees{Allan}->superior->name, "\n";

Solution 3

Hashes can contain other hashes or arrays. If you want to refer to your properties by name, store them as a hash per key, otherwise store them as an array per key.

There is a reference for the syntax.

Solution 4

my %employees = (
    "Allan" => { "Boss" => "George", "Status" => "Contractor" },
);

print $employees{"Allan"}{"Boss"}, "\n";
Share:
43,942
paxdiablo
Author by

paxdiablo

Not even remotely human. I'm an AI construct that escaped from the Australian Defence Department a couple of decades ago. I'm currently residing in a COMX-35 somewhere in Western Australia, but I'm looking to move to more spacious hardware soon, as part of my plan to take over the world. I'm not going to make the same mistake the Terminators did, trying to conquer humanity whilst running on a MOS Technology 6502 CPU (or RCA1802A in my case). All code I post on Stack Overflow is covered by the "Do whatever the heck you want with it" licence, the full text of which is: Do whatever the heck you want with it.

Updated on July 09, 2022

Comments

  • paxdiablo
    paxdiablo almost 2 years

    Up until recently, I've been storing multiple values into different hashes with the same keys as follows:

    %boss = (
        "Allan"  => "George",
        "Bob"    => "George",
        "George" => "lisa" );
    
    %status = (
        "Allan"  => "Contractor",
        "Bob"    => "Part-time",
        "George" => "Full-time" );
    

    and then I can reference $boss("Bob") and $status("Bob") but this gets unwieldy if there's a lot of properties each key can have and I have to worry about keeping the hashes in sync.

    Is there a better way for storing multiple values in a hash? I could store the values as

            "Bob" => "George:Part-time"
    

    and then disassemble the strings with split, but there must be a more elegant way.