Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic

How to add to hash of a hash of an array.!

by Doozer (Scribe)
on Jun 13, 2013 at 10:02 UTC ( #1038714=perlquestion: print w/replies, xml ) Need Help??
Doozer has asked for the wisdom of the Perl Monks concerning the following question:


I have a pretty complicated (for me anyway) hash setup as shown in the example snippet below:

my %hash = ( 'A1' => { 'B1' => 'Value', 'B2' => { 'C1' => [arrayitem1, arrayitem2, arrayitem3,], 'C2' => [arrayitem1, arrayitem2, arrayitem3,], } }, )

What I want to do is check whether C1 or C2 exists. If it exists, I want to add another item to its array. If C1 or C2 does not exist, I want to create it as an array reference and add an item to its array.

At the moment my code looks something like this:

if (exists $hash{'A1'}{'B2'}{'C1'}) { push ( @{ $hash{'A1'}{'B2'}{'C1'}}, arrayitem4; } else { $hash{'A1'}{'B2'} = {'C1' => [arrayitem1]}; }

The code doesn't work as I get various "Can't use string ("") as a HASH ref while "strict refs" in use" errors. I am getting very confused with all of the searching I have done to find the answer so would really appreciate it if someone could point me in the right direction.

The aim is that B2 would be a 'Test Results' key. The 'C' keys would refer to dates and then the arrays within them would be the data of the results (single line sentences) for that dates tests

Replies are listed 'Best First'.
Re: How to add to hash of a hash of an array.!
by tangent (Priest) on Jun 13, 2013 at 10:19 UTC
    Where you have
    $hash{'A1'}{'B2'} = {'C1' => [arrayitem1]};
    you are clobbering $hash{'A1'}{'B2'}{'C2'}

    Try changing it to:
    $hash{'A1'}{'B2'}{'C1'} = [arrayitem1];
Re: How to add to hash of a hash of an array.!
by LanX (Chancellor) on Jun 13, 2013 at 10:19 UTC
    You are posting broken code, the '(' after push is never closed. Did this ever compile for you?

    Perl does autovivification, so no need to test for existence.

    Just push (and use valid syntax)!

    DB<105> push @{ $hash{A1}{B2}{C1} }, "arrayitem4"; => 1 DB<106> \%hash => { A1 => { B2 => { C1 => ["arrayitem4"] } } } DB<107> push @{ $hash{A1}{B2}{C1} }, "arrayitem1"; => 2 DB<108> \%hash => { A1 => { B2 => { C1 => ["arrayitem4", "arrayitem1"] } } } DB<109> push @{ $hash{A1}{B2}{C2} }, "arrayitem2"; => 1 DB<110> \%hash => { A1 => { B2 => { C1 => ["arrayitem4", "arrayitem1"], C2 => ["arrayite +m2"] }, }, }

    Cheers Rolf

    ( addicted to the Perl Programming Language)

Re: How to add to hash of a hash of an array.!
by roboticus (Chancellor) on Jun 13, 2013 at 11:38 UTC


    If the item doesn't exist, you're just going to create it anyway, so why not just use:

    push @{$hash{A1}{B2}{C1}}, $item;

    Without showing more of your code, we can't be sure exactly what your problem is. I'm suspecting that it's due to the fact that sometimes your B-level variable is a string and sometimes it's a hash reference. Perhaps $hash{A1}{B2} was a string a moment before executing the code you've shown--that would be enough to cause the problem:

    $ perl Can't use string ("") as a HASH ref while "strict refs" in use at ttt3 line 7. * /W/P/PM/ monitor_saints; check TODO_LIST $ cat #!/usr/bin/perl use strict; use warnings; use Data::Dumper; my %hash; $hash{A1}{B2} = ""; if (exists $hash{A1}{B2}{C1}) { print "Baz!\n"; }


    When your only tool is a hammer, all problems look like your thumb.

Re: How to add to hash of a hash of an array.!
by Anonymous Monk on Jun 13, 2013 at 10:16 UTC

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1038714]
Approved by Corion
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others pondering the Monastery: (7)
As of 2017-07-28 17:11 GMT
Find Nodes?
    Voting Booth?
    I came, I saw, I ...

    Results (431 votes). Check out past polls.