Search code examples
perlhashcopyclone

Creating sub-hashes in main hash


I want to create a hash of hashes in Perl without having to explicitly write everything out. I understand that I could use dclone to do something like:

use Storable 'dclone';

my %main_hash = (
   A => {},
   B => {},
   C => {},
);

my %sub_hash = (
   a => [],
   b => [],
   c => [],
   d => [],
);

foreach my $main_key (keys %main_hash) {
   $main_hash{$main_key} = dclone {%sub_hash};
}

Final result:

%main_hash:
   A => {
     a => [],
     b => [],
     c => [],
     d => [],
   },
   B => {
     a => [],
     b => [],
     c => [],
     d => [],
   },
   C => {
     a => [],
     b => [],
     c => [],
     d => [],
   },
);

Is there any way to do this repeated hash insertion without relying on dclone or some other imported module?


Solution

  • You can just put the %sub_hash declaration inside the loop and assign it to the main hash. Each loop iteration will be a new hash, you don't need dclone:

    my %main_hash = (
       A => {},
       B => {},
       C => {},
    );
    
    foreach my $main_key (keys %main_hash) {
        my %sub_hash = (
           a => [],
           b => [],
           c => [],
           d => [],
        );
       $main_hash{$main_key} = \%sub_hash;
    }
    
    use Data::Dumper;
    print Dumper \%main_hash;
    

    Output:

    $VAR1 = {
              'C' => {
                       'b' => [],
                       'a' => [],
                       'c' => [],
                       'd' => []
                     },
              'B' => {
                       'b' => [],
                       'a' => [],
                       'c' => [],
                       'd' => []
                     },
              'A' => {
                       'c' => [],
                       'd' => [],
                       'b' => [],
                       'a' => []
                     }
            };