Search code examples
arraysperldata-structureshashperl-data-structures

Hash in array in a hash


I'm trying to identify the output of Data::Dumper, it produces the output below when used on a hash in some code I'm trying to modify:

print Dumper(\%unholy_horror);
$VAR1 = {
      'stream_details' => [
                            {
                              'file_path' => '../../../../tools/test_data/',
                              'test_file' => 'test_file_name'
                            }
                          ]
    };

Is this a hash inside an array inside a hash? If not what is it? and what is the syntax to access the "file path" and "test_file" keys, and their values.

I want to iterate over that inner hash like below, how would I do that?

while ( ($key, $value) = each %hash )
{
    print "key: $key, value: $hash{$key}\n";
}

Solution

  • You're correct. It's a hash in an array in a hash.

    my %top;
    $top{'stream_details'}[0]{'file_path'} = '../../../../tools/test_data/';
    $top{'stream_details'}[0]{'test_file'} = 'test_file_name';
    
    print Dumper \%top;
    

    You can access the elements as above, or iterate with 3 levels of for loop - assuming you want to iterate the whole thing.

    foreach my $topkey ( keys %top ) { 
       print "$topkey\n";
       foreach my $element ( @{$top{$topkey}} ) {
           foreach my $subkey ( keys %$element ) { 
               print "$subkey = ",$element->{$subkey},"\n";
           }
       }
    }
    

    I would add - sometimes you get some quite odd seeming hash topologies as a result of parsing XML or JSON. It may be worth looking to see if that's what's happening, because 'working' with the parsed object might be easier.

    The above might be the result of:

    #JSON
    {"stream_details":[{"file_path":"../../../../tools/test_data/","test_file":"test_file_name"}]}
    

    Or something similar from an API. (I think it's unlikely to be XML, since XML doesn't implicitly have 'arrays' in the way JSON does).