in reply to Re^2: Hash of Arrays or Arrays of arrays? and how proceed?
in thread Hash of Arrays or Arrays of arrays? and how proceed?

I'll try to give you a skeleton of that subroutine:

sub ExtractDatabaseFields { my $file= shift; my @databases= @_; my %result; foreach my $database (@databases) { my @fields= ... #extract data from database my $nextfield= .... #find next field $result{$database}{next}= $nextfield; $result{$database}{fields}= \@fields; } return \%result; } #------------------- # Accessing my $result= ExtractDatabaseFields($file,@databases); #print next available field of database 27: print $result->{"27"}{next}; #extract the fourth field from database 27: my $field3= $result->{"27"}{fields}[3]; #add another field to database 27: push @{$result->{"27"}{fields}}, "whatever"; #loop over the fields of database $x: foreach $field ( @{$result->{$x}{fields}} ) { .... }

The resulting data structure would be a HashOfHashOfArrays, not a HashofArrays, but this makes the access to the data much clearer. If this isn't what you wanted you might give a more elaborate example

Replies are listed 'Best First'.
Re^4: Hash of Arrays or Arrays of arrays? and how proceed?
by paride (Initiate) on Aug 03, 2011 at 08:42 UTC

    now all work ....but I realized I need a more complex solution... :(

    I've transformed $nextfield in an array because of two different DB could have 1 ore more fields less than the other one, and the result is OK! printing Dumper (when @Database is ("5","6"):

    $VAR1 = \'6'; $VAR2 = 'AP', 'AO' ; $VAR3 = 'AA', 'AB', 'AC', 'AD', 'AE', 'AF', 'AG', 'AH', 'AI', 'AJ', 'AK', 'AL', 'AM', 'AN' ;

    But to proceed correctly I need a different @fields($VAR3) for every database, and to reach the top of my desired target I would like to add other attributes to the sigle field. For example AA,5(dimension),N(numeric) etc.

    I know it's very complex jethro, when I start with the idea to do this script I didn't expect it will be so complex. But I think this could be an excellent way to learn perl in dept

      Oh yes, you will be an expert on references and complex data structures after this ;-)

      One advice: You could store your attributes (i.e. AA, 5 'N' etc.) in strings (concatenated by ':' for example) or in arrays (i.e. index 0 would be 'AA', index 1 the dimension...). But usually the most maintainable way to do this is with a hash.

      #add values $fields{$database}[$fieldno]{dimension}=5; $fields{$database}[$fieldno]{type}='N'; # check if an attribute 'something' exists if (exists $fields{$database}[$fieldno]{something}) {

        Thanks, I've choosen the string solution (AA,5,N...) and it work perfectly, but if I need to have a different @fields stored for each database? it works in sub but outside when I do the loop for each $Database to re-print dumper using

        Dumper(\$Database,\@nextfield,\@fields);

        It print only the fields of the "last" $Database acquired... did you have an idea about it?

Re^4: Hash of Arrays or Arrays of arrays? and how proceed?
by paride (Initiate) on Jul 29, 2011 at 16:02 UTC

    Excellent!!! Very Difficult... but Excellent!! THANK YOU VERY MUCH

      ...only another question (...for me it's not so clear...)

      using strict...

      if I declare in a sub my $variable and I need to return this $variable outside to use it with another sub, did I need to declare it outside the sub (i.e. our $variable)?

Re^4: Hash of Arrays or Arrays of arrays? and how proceed?
by paride (Initiate) on Aug 02, 2011 at 09:58 UTC

    I've got a compiling error on

    $result{$database}{next}= $nextfield; $result{$database}{fields}= \@fields;

    Use of uninitialized value in hash element

    but I've declared "my %result;" at the start of the sub

    Did I miss something? Did I need to declare $next and $fields?

      The uninitialized value in hash element(!) would be $database. In such cases it is a good debugging technique to add statements like the following to your code to observe what happens:

      use Data::Dumper; #at the start of the script ... print Dumper(\$database,\$nextfield,\@fields); $result{$database}{next}= $nextfield; $result{$database}{fields}= \@fi +elds; #<--- the problematic line

      A simple print "\$database is $database\n" would do as well, but Data::Dumper is to print for debugging like a lawnmower is to a scissor for cutting gras ;-).

      Look at the output and compare it to your expectations. Probably you will see an undef value printed for $database. Now you can retrace the steps, look how $database could get that value, insert "print Dumper..." statements where you think it could go wrong. Maybe it is a regex that didn't match anything or maybe you put a value in an array into $a[1] but not in $a[0], which would leave the first array value undefined...