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

5

24

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.

Rigadoon answered 10/10, 2008 at 7:47 Comment(1)
This is a great reminder of why the Perl Data structure cookbook is such a great resource.Arlynearlynne
G
26

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
Griseous answered 10/10, 2008 at 8:0 Comment(4)
That looks okay. I guess I can add another chum with $chums{"Greg"} = {"Boss" => "Lisa", "Status" => "Fired"} but how do I go about adding a wife to Bob? Would that be $chums{"Bob"}{"Wife"} = "Carol"?Rigadoon
Also, why the "->". It seems to function without these.Rigadoon
TIMTOWDI :), you can use it without them, and yes, your way to add a wife is correctGriseous
This is a great reminder of the value of the perldsc. This should be required reading for PHP, Python, Ruby and Perl programmers.Arlynearlynne
K
23

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";
Keratoid answered 10/10, 2008 at 8:16 Comment(1)
This has the benefit that it can be enhanced in the future.Investigation
R
4

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.

Rent answered 10/10, 2008 at 8:3 Comment(0)
H
2
my %employees = (
    "Allan" => { "Boss" => "George", "Status" => "Contractor" },
);

print $employees{"Allan"}{"Boss"}, "\n";
Howlyn answered 10/10, 2008 at 8:5 Comment(0)
M
0

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

works great but is there a faster way to enter the data?

I am thinking of something like

%chums = (qw, x)( Allan Boss George Status Contractor Bob Boss Peter Status Part-time)

where x = the number of secondary keys after the primary key, in this case x = 2, "Boss" and "Status"

Mutation answered 22/12, 2013 at 21:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.