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

Thank you very much jethro! I'll search better on the example, even if for me it's difficult convert the fixed examples (@array 1,2,3,red) with the parametrical solution.

Answering to your first question I would like to pass to the subroutine only the @Databeses array obtained in the Environment defined section and the Table ($file) in which i would like to obtain results. The subroutine (as first instance) have to give me (for every Database of the environment) an array of ordered fields, and a scalar conteining the next available field. I've thinked to an hash but I've not understand how could I pass to the hash the @Database and how I could populate it with the Array that I obtain

For the second suggestion thanks very much also if I'm a beginner I would like to point directly to the best possible solution.

  • Comment on Re^2: Hash of Arrays or Arrays of arrays? and how proceed?

Replies are listed 'Best First'.
Re^3: Hash of Arrays or Arrays of arrays? and how proceed?
by jethro (Monsignor) on Jul 29, 2011 at 15:36 UTC

    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

      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}) {

      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)?

      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...