Limbic~Region has asked for the wisdom of the Perl Monks concerning the following question:

All:
I am wondering what general approach you would use to solve the following problem:
  • You have a loop of some sort
  • In the body of the loop, an array is built by doing a lot of calculations
  • For the purpose of making a uniform column output - you push the value to an array or use 0 for a placeholder
  • At the end of the loop, you would like to print out totals for each column

    For instance:

    #!/usr/bin/perl -w use strict; $\ = "\n"; foreach my $row ( 1 .. 10 ) { my @output; foreach my $column ( 1 .. 10 ) { push @output , $column; } print join ',' , @output; } # print column totals here
    Now this is pretty easy to do by just looking at it, there will be exactly 10 rows and 10 columns. Each column will be the same number so the total will be 10, 20, 30, etc.

    My question is how would you do this if the number of columns was fixed, but the number of rows might vary depending on your data. Furthermore - the code to populate the the @output array is complicated and isn't as easy to determine as the simple foreach loop in my example. I was thinking of an AoA, but I can't get my head wrapped around how to process it afterwards.

    Any thoughts?

    Thanks in advance - L~R

  • Replies are listed 'Best First'.
    Re: Multi-Column Totals
    by bart (Canon) on May 07, 2003 at 22:20 UTC
      Here's the suggestion I offered in the Chatterbox. It keeps an array of running totals:
      #!/usr/bin/perl -w use strict; $\ = "\n"; my @total; foreach my $row ( 1 .. 10 ) { my @output; foreach my $column ( 1 .. 10 ) { push @output , $column; $total[$#output] += $column; } print join ',' , @output; } # print column totals here print 'total:'; print join ',' , @total;
      which gives:
      1,2,3,4,5,6,7,8,9,10
      1,2,3,4,5,6,7,8,9,10
      1,2,3,4,5,6,7,8,9,10
      1,2,3,4,5,6,7,8,9,10
      1,2,3,4,5,6,7,8,9,10
      1,2,3,4,5,6,7,8,9,10
      1,2,3,4,5,6,7,8,9,10
      1,2,3,4,5,6,7,8,9,10
      1,2,3,4,5,6,7,8,9,10
      1,2,3,4,5,6,7,8,9,10
      total:
      10,20,30,40,50,60,70,80,90,100
      
    Re: Multi-Column Totals
    by Abigail-II (Bishop) on May 07, 2003 at 22:28 UTC
      Just add a few lines:
      my @totals; foreach my $row ( 1 .. 10 ) { my @output; foreach my $column ( 1 .. 10 ) { push @output , $column; } $totals [$_] += $output [$_] for 0 .. $#output; print join ',' , @output; } # print column totals here print "@totals";

      This will even work if the rows don't all have the same size.

      Abigail

    Re: Multi-Column Totals
    by shemp (Deacon) on May 07, 2003 at 22:24 UTC
      if you dont know in advance how many elements are in an array that you want to loop through, a couple of approaches may work:
      foreach my $row (@rows) { ... }
      will loop through each row, but then you lose the row number that you're on, if thats important. Also, this approach creates an anonymous array for the foreach to loop through. With big arrays this can be memory expensive.

      Another approach that avoinds these issues is this:
      for my $i (0 .. $#rows) { ... # something with $rows[$i] }
      This approach just asks the array how big it is, and then may proceed like your original code.
      Hope this is what you're asking for.
    Re: Multi-Column Totals
    by Skeeve (Parson) on May 08, 2003 at 08:12 UTC
      untested code...
      @rows= ( ([1..10]) x 10 ); foreach $row (@rows) { $output=''; $i=0; foreach $col (@$row) { $output.=$col . ','; $total[$i++]+=$col; } chop($output); print $output,"\n"; } print join(',',@total),"\n";
    (jeffa) Re: Multi-Column Totals
    by jeffa (Bishop) on May 08, 2003 at 15:36 UTC
      Well ... if you wanted everything wrapped in an XHTML table ...
      use strict; use warnings; use DBIx::XHTML_Table; my $row = [map [1..10], 1..10]; my $head = [map "head$_", 1..10]; print DBIx::XHTML_Table->new($row,$head)->calc_totals->output;

      jeffa

      L-LL-L--L-LL-L--L-LL-L--
      -R--R-RR-R--R-RR-R--R-RR
      B--B--B--B--B--B--B--B--
      H---H---H---H---H---H---
      (the triplet paradiddle with high-hat)