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

Enlightened Ones!

I, a most humble novice, would like to construct a database (for Excel) from a number of extracted sources. To save it as a file which then can be read into Excel or other application I would have to print out the results with rows constituting units and the values of the variables in the columns.

My first thought was to use a hash for each unit and then assign the same set of keys to each hash. As I have several thousands of units/rows it would be nice to generate "generic" hashes, i.e. %1, %2, %3, %4 and so on. Furthermore, it would be convenient to manipulate all of them (e.g., create the same keys, print all of them in new lines) simultaneously in loops. I recall that something like this existed in the good old days of Turbo Pascal. But how does this work in PERL if it works at all?

The description on CPAN covers hashes of hashes, which might be the thing to do, but not of a generic type. I also didn't find anything pertaining to this question on other perl tutorials.

Enlightenment would be greatly appreciated!

Replies are listed 'Best First'.
Re: "Generic" variables/Hash of hashes
by mirod (Canon) on Feb 14, 2005 at 12:32 UTC

    I think what you are missing here is that the values in a hash (or in an array or in a scalar) can be references. This I think makes what you call generic type. And you don't have to create the same keys in all of them, you can just use them.

    So the structure you are looking for is either a hash of hashes, or more likely an array of hashes. You would just create a hash for each row, and push a reference to it into the array:

    my @database; # loading the db while( my %row= get_a_row()) { push @database, \%row; } # put the row in the db # printing the results # first the keys my $row1= $database[0]; # I assume there is at least 1 row # and thet all rows have the same keys my @keys= keys %$row1; # %$row1 returns the hash referenced by $row1 print join( "\t", @keys), "\n"; # or however you want to print them # print the values, tab separated, 1 row/line foreach my $row (@database) { print join( "\t", values %$row), "\n"; } # same as with keys, just + more concise }

    (untested code)

Re: "Generic" variables/Hash of hashes
by sh1tn (Priest) on Feb 14, 2005 at 11:33 UTC
    Please, take a look at:

    perldoc perldsc
    perldoc perlref

Re: "Generic" variables/Hash of hashes
by dragonchild (Archbishop) on Feb 14, 2005 at 13:33 UTC
    If you know how to use DBI (which would be a good thing to learn), you could then use one of the following DBD modules: DBI has a tutorial, plus there are hundreds of good threads on the topic in the monastery.

    Being right, does not endow the right to be rude; politeness costs nothing.
    Being unknowing, is not the same as being stupid.
    Expressing a contrary opinion, whether to the individual or the group, is more often a sign of deeper thought than of cantankerous belligerence.
    Do not mistake your goals as the only goals; your opinion as the only opinion; your confidence as correctness. Saying you know better is not the same as explaining you know better.

Re: "Generic" variables/Hash of hashes
by Taulmarill (Deacon) on Feb 14, 2005 at 12:37 UTC
    the fastest would shurely be an Array of Arrays (aka 2-dimensional Array). you could also create a Hash of Arrays or an Array of Hashes, depending on how you want to manipulate the data.

    1. what do you actualy want? what type on manipulation or processing will be done to the data?
    2. what does your input data look like?
      The data input consists mainly of strings and some dates. Ultimately I want to construct something like a storage inventory. The records that form the input (and should be printed in the first database in rows) give you delivery date, sales date, etc. and a description of the goods. The second database should then give me the number of certain goods per period, that means I would have to run through the records and check if there has been a delivery containing the goods and how much has been sold (think of sales as a negative delivery) up to a certain point, so that I can calculate the inventory for that particular time period.
        i think you should use an Array of Arrays. if you want more verbose code, you could use constants to store whitch row has what in it.

        you should read perlref and perllol.

        the main idea in perl data structures is, that you store a row in an array and store references to those arrays/rows in another array, so you get something that is usable as two dimensional array.
Re: "Generic" variables/Hash of hashes
by holli (Abbot) on Feb 14, 2005 at 12:28 UTC
    So if i understand you right, you want to create a tab-delimited file with the field-names in the first line, from a number of sources. This should be easy enough, if only weŽd know what these sources are.
    Can you provide some sample data and show us what you have tried so far (if any).


    holli, /regexed monk/