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

I am sure that this has been asked before but I guess I CAN'T figure out the correct search mojo.

    1. Is this the correct way to write this data structure? Suggestions?

    2. How do I access the size of the 'disallowed' array?

    3. What is the best way to foreach this array?
my %t_type = ( 'a' => { 'chance' => {'low' => 2, 'high' => 12, 'percent' => 50}, 'range' => {'number' => '','disallowed' => ['none','1','2']}, } ); print "$t_type{'a'}{'magic'}{'disallowed'}[2] \n";
I am not having problems accessing the array slice but getting the entire array info is proving troublesome.

thanks in advanced

Replies are listed 'Best First'.
Re: array in hash in hash access
by davido (Cardinal) on Aug 25, 2004 at 03:55 UTC

    It is one correct way to write the datastructure. One of the easiest ways of displaying an entire datastructure is to use Data::Dumper. With the data structure you posted, you would use Data::Dumper like this:

    use strict; use warnings; use Data::Dumper; my %t_type = ( 'a' => { 'chance' => {'low' => 2, 'high' => 12, 'percent' => 50}, 'range' => {'number' => '','disallowed' => ['none','1','2']}, } ); print Dumper \%t_type;

    The datastructure you've written is a hash of hashes of hashes, where one of the innermost hash's elements references an array.

    What exactly are you trying to do, iterate over the entire structure? Take a slice of a portion of it? What do you need? One place to look for some answers is perldsc: The Perl Datastructure Cookbook; included in the POD of every complete Perl distribution.

    You can dereference the deepest level array in scalar context to get its size.


    Dave

Re: array in hash in hash access
by grantm (Parson) on Aug 25, 2004 at 04:04 UTC
    How do I access the size of the 'disallowed' array?
    my $length = @{$t_type{'a'}{'range'}{'disallowed'}}; print "Length: $length\n";
    What is the best way to foreach this array?
    print "$_\n" foreach (@{$t_type{'a'}{'range'}{'disallowed'}})
Re: array in hash in hash access
by bobf (Monsignor) on Aug 25, 2004 at 06:25 UTC

    Just adding a few things to the replies by davido and grantm:

  • In addition to perldsc, you might also want to look at perlref and perlreftut (since what you're really doing here is dereferencing anonymous data structures
  • When using complex data structures, sometimes it helps to think about them in English rather than in code (granted, in perl this is often nearly the same). A translation of foreach my $element ( @{ $t_type{'a'}{'range'}{'disallowed'} } ) is "for each element in the anonymous array refered to by the hash element $t_type{'a'}{'range'}{'disallowed'}".
  • Similarly, you could get a list of the keys in the anonymous hash refered to by $t_type{'a'}{'chance'} using keys %{ $t_type{'a'}{'chance'} }.
  • HTH

    Update: fixed typo (there is no 'foreach' in English!)(thanks revdiablo!).

Re: array in hash in hash access
by Mr_Jon (Monk) on Aug 25, 2004 at 08:06 UTC
    One more thing to add. When you use =>, the fat comma operator, there's no need to quote the keys on the left hand side ('low', 'high', 'percent' ...), since these are automagically interpreted as strings (unless they contain a space).

    See perlop for more details.
Re: array in hash in hash access
by Prior Nacre V (Hermit) on Aug 25, 2004 at 11:19 UTC

    With reference to accessing the data, the following construct is also valid:

    $#{ expr_returning_arrayref }

    The expr_returning_arrayref is useful in many situations. In an OO application, you might access your array size like this (somewhat contrived for the purpose of example):

    my $size = @{ $self->get_disallowed_array };

    Of course, the accessor method would probably use something along the lines of previous replies.

    With reference to everything else, excellent replies above.

    Regards,

    PN5