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

Hi, I have to create a multileve hash. I am creating a hash with only one key.
foreach $key(sort {$a<=>$b} keys(%resultHoA)){ $statushash{$resultHoA{$listcols[0]}[0]}='0'; }
Array can contain 'n' elements. For each element of array i need to create one level. Here is an Example: if arr hash 3 (may vary) elts hash should be like this
$hash{arr[1]}{arr[1]}{arr[2]}.
I think the explains my requirement clearly than my description. Thanks in Adv.

Replies are listed 'Best First'.
Re: Building Multi-Level Hash dynamically
by holli (Abbot) on Dec 05, 2006 at 13:17 UTC
    like so?
    use warnings; use strict; use Data::Dumper; my %hash = (); my @array = (1,2,3}; my $href = \%hash; for ( @array ) { $href->{$_} = {}; $href = $href->{$_}; } print Dumper (\%hash); #'1' => { # '2' => { # '3' => {} # } # }


    holli, /regexed monk/
Re: Building Multi-Level Hash dynamically
by madbombX (Hermit) on Dec 05, 2006 at 13:15 UTC
    It sounds to me like you need to create a HoA (Hash of Arrays). However, creating a datastructure 3 levels deep with a hash of array of arrays (HoAoA) may not be what you want. Without actually showing us some sample data, it is difficult for us to determine what kind of data structure you need and how to define/initialize it. You may want to look at planetscape's Re: How can I visualize my complex data structure? to get a better idea of what it is you want and how to better organize. This should also give you an idea of how to access data within the data structure.
Re: Building Multi-Level Hash dynamically (diver)
by tye (Sage) on Dec 05, 2006 at 16:37 UTC

    See Data::Diver (or search here for nearly exactly that title to find several previous discussions of this, for example: dynamic hash).

    - tye        

Re: Building Multi-Level Hash dynamically
by Firefly258 (Beadle) on Dec 05, 2006 at 13:20 UTC
    I'm not sure I really follow you, but I'm hoping I understood what you want from the last expression.
    #!/usr/bin/perl -W use strict; my $hoh; my @array = qw|abc def ghi jkl|; my $eval_string = '$hoh->{' . (join '}{', @array) . '} = q|hello world|'; eval "$eval_string"; print $hoh->{abc}{def}{ghi}{jkl}; __END__ ___output___ hello world

    The key is to use eval in string form. That way you can construct perl code using perl and execute it to affect the current program.


    perl -e '$,=$",$_=(split/\W/,$^X)[y[eval]]]+--$_],print+just,another,split,hack'er
      The key is to use eval in string form.

      It really almost never is. String eval is great if you want to generate code from something that looks like code it's a lot less great if you want to generate data structures. Your code is pretty susceptible to errors if @array happens to contain certain characters. Also, it's extremely inefficient to use the compiler for this kind of thing.

        What would be your method of choice to solve OP's problem?

        My code is susceptible to a lot of errors, I'm aware, I hope it never gets used "as is" in production code. :) As for the types of characters in the array that could cause mayhem, could you point me in the direction of them? I'd very much appreciate that.

        Also, it's extremely inefficient to use the compiler for this kind of thing

        If i'm not mistaken and understand it right, the contents to a string form of eval are not known at compile time, and when the interpreter does get around to compiling and evaling the string, it is executed in the same way statically typed code (if that's the right term) is. So I'm not sure I understand what you mean. Can you please clarify?

        I'm aware of the dangerous implications of eval"" but I also have an inclination to think that evaling code for constructing other code/data structures might be more effecient than running through various loops and conditional constructs and assigning to references to get a structure constructed. It definitely is faster. Sriram Srinivasan has a section in advprog that deals with Using Eval for Efficiency to construct faster regular expressions amongst other useful things.



        perl -e '$,=$",$_=(split/\W/,$^X)[y[eval]]]+--$_],print+just,another,split,hack'er