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

Dear Monks, I am trying to format a table in html. I have a list of column names (20) and then a list of values. The values are listed in order of the column names but there may be more than one set of values. I am trying to format them so they look like this:
my @column_names = ('col1', 'col2','col3'); my @values = ('val1','val2','val3','val4','val5','val6'); ------------ # output: col1 val1 val4 col2 val2 val5 col3 val3 val6
Please can anyone help?
my $c2 = @column_names; for (my $i=0; $i<@column_names;$i++) { print qq(<tr><td>$column_names[$i]</td>); } + + for (my $i=0; $i<@values; $i+=$c2) { print "<td>$values[$i]</td>\n"; } print qq(<tr>);

Replies are listed 'Best First'.
Re: perl loops + html tables
by macPerl (Beadle) on Jan 10, 2005 at 14:05 UTC
    Pedantry: they are not COLS when they are horizontal ! They are ROWS ! ;-)

    I'm very new to HTML::Template but think it would work very well for you in this scenario.
    There is an example of a vertical table at
    http://html-template.sourceforge.net/article.html
    and I don't think it would take a lot to transpose it for your purposes.

    Long story short, you will need to set up the data so that you are passing an array to the template. That array will hold references to hashes which will hold your data.

    Note: I had some initial teething problems with HTML::Template which were caused by passing veriables to a template but not using them within the template. Other than that "it does what it says on the tin".
Re: perl loops + html tables
by Jaap (Curate) on Jan 10, 2005 at 12:17 UTC
    You're almost there. Adding something to open and close a <tr> at the right point should help:
    print "<tr>"; for (my $i = 0; $i<@values; $i++) { if (($i % scalar(@column_names)) == 0) { print "</tr>\n<tr>"; } print "<td>$values[$i]</td>\n"; } print "</tr>";
    code is UNTESTED.
    The $i % 3 equals to 0 if $i is 0 or 3 or 6 or 9 or ...

      code is UNTESTED.

      And wrong. While the output you generate is useful, it's not what the OP specified. You forgot to output the column names and probably didn't look at the example output at all, as that specifies horizontal "columns". Turning a table 90 degrees results in messier code than the nice looking thing you produced.

      Juerd # { site => 'juerd.nl', plp_site => 'plp.juerd.nl', do_not_use => 'spamtrap' }

Re: perl loops + html tables
by Juerd (Abbot) on Jan 10, 2005 at 13:25 UTC

    my @column_names = "col1" .. "col3"; my @values = "val1" .. "val6"; my @td = [ @column_names ]; push @td, [ splice @values, 0, scalar @column_names ] while @values; print "<table>\n"; for my $i (0 .. $#column_names) { print "<tr>", map("<td>$_->[$i]</td>", @td), "</tr>\n"; } print "</table>\n";
    But shouldn't col1 .. col3 be TH instead of TD?
    my @th = "col1" .. "col3"; my @values = "val1" .. "val6"; my @td; push @td, [ splice @values, 0, scalar @th ] while @values; print "<table>\n"; for my $i (0 .. $#th) { print "<tr><th>$th[$i]</th>", map("<td>$_->[$i]</td>", @td), "</tr>\n"; } print "</table>\n";

    Juerd # { site => 'juerd.nl', plp_site => 'plp.juerd.nl', do_not_use => 'spamtrap' }

Re: perl loops + html tables
by CountZero (Bishop) on Jan 10, 2005 at 13:09 UTC
    Are you sure about your output? Shouldn't it be
    col1 col2 col3 val1 val2 val3 val4 val5 val6

    CountZero

    "If you have four groups working on a compiler, you'll get a 4-pass compiler." - Conway's Law

      The output needs to be the other way round (like I said in the post).

      Cheers

        So col is more of a row?

        This code will do the trick:

        use strict; my @column_names = ('col1', 'col2','col3'); my @values = ('val1','val2','val3','val4','val5','val6', 'val7', 'val +8'); my $number_of_rows = @column_names; my $number_of_values = @values; my $row_number; print '<table>'; foreach my $row (@column_names) { print '<tr><td>',$row,'</td>'; for (my $value_number=$row_number; $value_number<$number_of_values +; $value_number+=$number_of_rows) { print '<td>',$values[$value_number],'</td>'; } $row_number++; print '</tr>'; } print '</table>';
        Note that the number of values does not have to be an integer multiple of the number of rows.

        CountZero

        "If you have four groups working on a compiler, you'll get a 4-pass compiler." - Conway's Law

Re: perl loops + html tables
by nedals (Deacon) on Jan 11, 2005 at 07:36 UTC
    And here's a very easily understood solution....
    use strict; my @column_names = ('col1', 'col2','col3'); my @values = ('val1','val2','val3','val4','val5','val6'); for (0..$#column_names) { print qq(<tr><td>$column_names[$_]</td><td>$values[($_*2)]</td><td +>$values[($_*2)+1]</td></tr>\n); }
Re: perl loops + html tables
by punch_card_don (Curate) on Jan 10, 2005 at 13:49 UTC
    mistake erased.
      Sorry, - that should be:
      my @column_names = ('col1', 'col2','col3'); my @values = ('val1','val2','val3','val4','val5','val6'); my $num_vals = $#values / $#column_names; print "<table>\n"; for $r (0 .. $#column_names) { print "<tr><td>$column_names[$r]</td>"; for $c (0 .. $num_vals - 1) { $val = ($r*$num_vals)+$c; print "<td>$values[$val]</td>"; } print "</tr>\n"; } print "</table>":
      Where it's assumed you have an integer multiple of values for each column name. If not, putin a pre-check:
      if ($values[$val]) {...} else {last;}

      Forget that fear of gravity,
      Get a little savagery in your life.

Re: perl loops + html tables
by naChoZ (Curate) on Jan 11, 2005 at 14:57 UTC

    Just thought I'd mention a module that a recently discovered that is quite handy with tables, HTML::QuickTable. I use it by looping through some records and populating a hash with some of the information.

    $Foo{ Bar }{ Baz } = "Value 1"; $Foo{ Bar }{ Quux } = "Value 2"; $Foo{ MoreBar }{ Baz } = "Value 3";

    HTML::QuickTable spits back:

    BazQuux
    BarValue 1Value 2
    MoreBarValue 3

    --
    "A long habit of not thinking a thing wrong, gives it a superficial appearance of being right." -- Thomas Paine
    naChoZ