Deal with hashes that are values of hashes as hash references, which is
really what they are.  As such, you will need to dereference them in
order to use them.  If you're going to be getting mixed data, and you're
not sure whether the reference is to an array or a hash, you can use the
ref() function.  

For example, if you need to cycle through the values of Level2B below,
try something like this:

        foreach(sort keys %{$struct->{LEVEL1A}->{Level2B}}){
           do something...
        }

This can quickly get confusing, so sometimes you might want to create a
new hash for legibility:

        my %hash = %{$struct->{LEVEL1A}->{Level2B}};
        foreach(sort keys %hash){
           do something...
        }
        
        my $hashref = $struct->{LEVEL1A}->{Level2B};
      do something;


I wrote the code below to play around with the idea of using a recursive
function to let me enumerate all of the levels without having to bother
with the complexity of the structure.  It's not the best example for
beginning, but it shows one way to do it.



##################################################

use strict;
use warnings;

my $struct = {
                LEVEL1A => { Level2A => {level3a => "a",
                                     level3b => "b"},
                               Level2B => {level3c => "c",
                                     level3d => "d"}
                         },
                LEVEL1B => { Level2C => [1,2,3,4,5] }
             };

#Takes a hash or array reference and
#the number of spaces to indent.
PrintRef($struct,3);


sub PrintRef{
   my $input = shift;
   my $tab = shift;
   my $tabmore = 0;
   
   #If it's an array
   if(ref($input) and ref($input) eq 'ARRAY'){
      Tab($tab,"+ ARRAYREF\n");
      Tab($tab + 3,"- ".join(',',@{$input})."\n");
      
   #If it's a hash
   }elsif(ref($input) and ref($input) eq 'HASH'){
      Tab($tab,"+ HASHREF\n");
      foreach my $key(sort keys %{$input}){
         if(ref($key)){
            PrintRef($key);
         }else{
            unless($tabmore){
               $tab += 3;
               $tabmore = 1;
            }
         }
         
         #Check each value to see if it's a ref
         if(ref($input->{$key})){
            PrintRef($input->{$key},($tab + 3));
         }else{
            Tab($tab,"- $key => ".$input->{$key}."\n");
         }
      }
   }
}

#Just a quick function for indenting
#Takes the number of spaces to indent and the
#text to print as arguments
sub Tab{
   my $indent = shift;
   my $text = shift;
   for(1..$indent){
      print ' ';
   }
   print $text;
}

##############################################



-----Original Message-----
From: Leonardo Mokarzel Falcon [mailto:[EMAIL PROTECTED] 
Sent: Monday, February 13, 2006 8:54 AM
To: beginners@perl.org
Subject: Manipulating complex structures...

# Hi fellows...

# I would like to handle a structure like this one:

$struct = {

       HASH1 => { hash1 => {A => "a", B => "b"},
                             hash2 => {C => "c", D => "d"}},

       HASH2 => { hash3 => [1,2,3,4,5]}                                 
};

# How do I go/* */through it and, for example, print the keys and values

of hash1, hash2 and  # the list associated with hash3.   




--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
<http://learn.perl.org/> <http://learn.perl.org/first-response>


Reply via email to