HarshaHegde has asked for the wisdom of the Perl Monks concerning the following question:

Dear Monks,

I have a HoH reference like this:

$VAR1 = { 'FOO' => { 'TABLE_NAME' => 'FOO', 'TABLE_TYPE' => 'REFERENCE' }, 'BAR' => { 'TABLE_NAME' => 'BAR', 'TABLE_TYPE' => 'REFERENCE' }, 'BAZ' => { 'TABLE_NAME' => 'BAZ', 'TABLE_TYPE' => 'CUSTOMER' } };
I am trying to turn this HoH inside out. i.e., I am trying to get:
$VAR1 = { 'REFERENCE' => [ 'FOO', 'BAR' ], 'CUSTOMER' => 'BAZ' };
The easiest option I can think of at this point is to create a HoA from the reference to the HoH. Something like:

my %HoA; foreach my $key (keys %$ref_to_HoH){ my $type = $ref_to_HoH->{$key}->{TABLE_TYPE}; if (exists $HoA{$type}){ push @{$HoA{$type}},$key; }else { $HoA{$type} = $key; } }
But this gives me the following error:

Can't use string ("FOO") as an ARRAY ref while "strict refs" in use at + .....

What am I doing wrong here? Greatly appreciate any help from the revered monks here.

Thanks,

Replies are listed 'Best First'.
Re: error creating hash of array
by graff (Chancellor) on Nov 04, 2007 at 18:13 UTC
    You want to get rid of the "if ... else ..." logic in your code snippet, and just always do the "push" for every iteration. As it is, each new hash key you create in %HoA gets a string value, and when you try to "push" a new element onto a string, you get the error.

    When you just do this:

    my %HoA; foreach my $key (keys %$ref_to_HoH){ my $type = $$ref_to_HoH{$key}{TABLE_TYPE}; push @{$HoA{$type}},$key; }
    Perl autovivifies a hash element with $type as the key whenever there is a new value in $type, and creates a ref to a new array as its value; it then pushes the string $key onto the array.
      Works great! Thanks graff!
Re: error creating hash of array
by mwah (Hermit) on Nov 04, 2007 at 18:39 UTC

    Another variant:

    ... my %HoA; push @{ $HoA{ $_->{TABLE_TYPE} } }, $_->{TABLE_NAME} for values %HoH; ...

    Remap array to scalar if only one entry

    ... for( values %HoA ) { $_ = $_->[0] if @$_ == 1 } ...

    Regards

    mwa