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

Greetings Fellow Monks:

I have found my self in need of organizing data from tables (Extracted with HTML::TableExtract). Right now I am storing the data in simulated multidimensional arrays. The code I have written seems to work, however, I don't think it is very efficient or proper. It seems there has to be a better way than what I am doing. Any suggestions or comments would be appreciated. Please let me know if I have not demonstrated well what I am trying to accomplish. Here is the code:

# Pull the tables out of the Web page # The output will be an array, with each component of it # array containing an entire row of the table, with each colomn # sepperated by a comma. my @tablerows = &FilterData(2, 0); my @aptable; # Now to split each element of the original array, and store # each column into the designated array for that column. # Initialize the column arrays my @tablecolumn0; my @tablecolumn1; my @tablecolumn2; my @tablecolumn3; my @tablecolumn4; my @tablecolumn5; # Spit each element of the original array, and push each part # into the appropriate column. foreach my $tablerow (@tablerows) { my @splitrow = split(/\,/, $tablerow); push (@tablecolumn0, @splitrow[0]); push (@tablecolumn1, @splitrow[1]); push (@tablecolumn2, @splitrow[2]); push (@tablecolumn3, @splitrow[3]); push (@tablecolumn4, @splitrow[4]); push (@tablecolumn5, @splitrow[5]); print "\n$tablerow"; } # Create references to the arrays thant contain table columns. # Store those references in an array to simulate # a multidiminsional array. my $column0 = \@tablecolumn0; push (@aptable, $column0); my $column1 = \@tablecolumn1; push (@aptable, $column1); my $column2 = \@tablecolumn2; push (@aptable, $column2); my $column3 = \@tablecolumn3; push (@aptable, $column3); my $column4 = \@tablecolumn4; push (@aptable, $column4); my $column5 = \@tablecolumn5; push (@aptable, $column5); # print two cells to see if it worked, which it does =) print "\n@aptable[1]->[1] is: @aptable[5]->[1]"; }

Replies are listed 'Best First'.
Re: Storing table data in a (simulated) multidimensional array
by davido (Cardinal) on Dec 08, 2004 at 16:18 UTC

    Use references right from the start. There's no need for an intermediate array. I think you would benefit from reading the following (in this order): perlreftut, perllol, and perldsc. References are also discussed in great depth in perlref, but the first three docs I mentioned are easier reads, and will get you going in the right direction.

    use strict; use warnings; use Data::Dumper; my @parsed_table = map { [ split /,/ ] } FilterData( 2, 0 ); print Dumper \@parsed_table;

    Dave

Re: Storing table data in a (simulated) multidimensional array
by jZed (Prior) on Dec 08, 2004 at 17:31 UTC
    My DBD::AnyData and AnyData modules have an HTMLtable format that uses HTML::TableExtract to pull information from local or remote HTML files or from HTML strings. The plain AnyData module puts the results in a multi-dimensional hash, the DBD::AnyData module puts it into a temporary in-memory DBI/SQL accessible database. If you use the DBD, you can then make use of the many modules that format DBI table data to display it any way you like. Here are examples of use of the two modules (assuming the table has columns user and city and that you want to find Fred Bloggs' city):
    #!perl -w use strict use AnyData; my $table = adTie( 'HTMLtable', $filename_url_or_string); while (my $row = each %$table) { printf "%s : %s\n", $row->{user},$row->{city}; } or ... #!perl -w use strict; use DBI; my $dbh=DBI->connect('dbi:AnyData:'); $dbh->ad_catalog( 'Test','HTMLtable', $filename_url_or string); print $dbh->selectrow_array('SELECT city FROM Test WHERE user = ?',und +ef,'Fred Bloggs');
    If the file or URL contains more than one table, you can pass HTML::TableExtract values defining the number or headings via the AnyData modules to specify which table you want.