Forum Moderators: coopster & phranque

Message Too Old, No Replies

Perl Table Column Coding

         

Brett_Tabke

1:46 pm on Oct 30, 2002 (gmt 0)

WebmasterWorld Administrator 10+ Year Member Top Contributors Of The Month



Ok, we've all run into the situation where we have a sequential list that need to be broken for display purposes into two or more columns.

What's your slickest code for doing that?

bobriggs

2:40 pm on Oct 30, 2002 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Here's a two column subroutine:
---------------------------------
my @orig = (1,2,3,4,5,6,7,8,9,10);

&twocolumn(@orig);

sub twocolumn {
my $num = @_;
my $half = ($num + 1)/ 2;#handles even or odd
my @col1 = @_[0..$half-1];#first column (will be longer than second if odd)
my @col2 = @_[$half..$num-1];#second column

while ($data1 = shift(@col1)) {
$data2 = shift(@col2);
print "$data1 $data2\n";#insert html formatting codes if output for web
}
}
---------------------------------
Probably could be improved.

andreasfriedrich

2:49 pm on Oct 30, 2002 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Neither Perl nor slick but working ok and in PHP:

$tr = sprintf('<tr class="%s">', $color); 
$mid = ceil(count($array)/2);
$string = array();
foreach($s as $key => $val) {
if ($i<$mid) {
$string[$i*2] = $tr . $s[$key];
} else {
$string[($i-$mid+1)*2-1] = $s[$key] . '</tr>';
}
$i++;
}
if($i%2<>0) $string[($i-$mid+1)*2-1] = '<td></td></tr>';
ksort($string);
$table = substr(implode('', $string),17,-5);

BTW I have no idea why I put the "=> $val" there. Useless and redundant code.

This prints the array "a,b,c,d,e,f,g" as

a ¦ e 
b ¦ f
c ¦ g
d ¦ h

Andreas

bobriggs

3:00 pm on Oct 30, 2002 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Here's a three column, again not slick. Assumes input array is already sorted and you want it like a phone book:

sub threecolumn {
my $num = @_;
my $third = ($num + 2)/ 3;#round to highest
my $half = ($num - $third + 1) / 2;#split second and third column, even/odd
my @col1 = @_[0..$third-1];#first column (will be longer than second if odd)
my @col2 = @_[$third..$third+$half-1];#second column
my @col3 = @_[$third+$half..$num-1];

while ($data1 = shift(@col1)) {
$data2 = shift(@col2);
$data3 = shift(@col3);
print "$data1\t$data2\t$data3\n";#insert html formatting codes if output for web
}
}

amoore

3:28 pm on Oct 30, 2002 (gmt 0)

10+ Year Member



I'd probably do something like this. It's pretty straightforward, but doesn't require that you count your data or figure stuff like that.

my @foo = (1..9);
printcolumns( \@foo );

sub printcolumns {
my $data = shift;
while( @$data ) {
my $left = shift( @$data );
print "$left";
my $right = shift( @$data );
print " $right" if ( $right );
print "\n";
}
}

andreasfriedrich

3:34 pm on Oct 30, 2002 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



... but you end up with something like this:

1 2 
3 4
5 6
7 8
9

instead of

1 6 
2 7
3 8
4 9
5 10

Andreas

dingman

3:41 pm on Oct 30, 2002 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Which, for some things, is exactly what you want.

For example, I have a gallery of photos from a trip to Haiti which includes a thumbnail page, arranged in five columns. The thumbnails are in a chronologicly ordered list, so it works better to have them run horizontally first, then wrap, as Amoore's code does. Depends on the data which presentation works best.

cminblues

5:54 pm on Oct 30, 2002 (gmt 0)

10+ Year Member



With this one [amoore&dingman formatted output style],
we can decide the # of columns.
[also some html <td></td> padding]

---BEGIN CODE---
$rawdata = '1-2-3-4-5-6-7-8-9-10-11-12-13-14-15-16-17-18';

@alldata = split(/\-/, $rawdata);

$columns = 4; #--- note that we need to define only here ;)

$cellpos = 1; #--- we start from the first element
while($alldata[($cellpos - 1)]) {
my $end = ($cellpos == @alldata);
my $still = $cellpos % $columns;
print STDOUT "<tr>" if(! (($cellpos -1) % $columns));
print STDOUT "<td>$alldata[($cellpos - 1)]</td>"; #-- single cell
#-- the line below is also for padding the rows in case of <td></td> in html
print STDOUT "<td></td>" x ($columns - ($cellpos % $columns)) . "<\/tr>" if($end && $still);
print STDOUT "</tr>\n" if(!$still); #-- we are on the end of the row
$cellpos++;
}

exit 0;
---ENDOF CODE---

cminblues