@array1 = qw(one two);
@array2 = qw(three four five);
@array3 = qw(Just another Perl Hacker !);
# make a 2D array
my @aoa = ( \@array1, \@array2, \@array3 );
# calculate max rows ( ie find array with largest number of members )
my $max_rows = 0;
for my $array_ref (@aoa) {
$max_rows = @$array_ref if @$array_ref > $max_rows;
}
# the number of columns is the number of array refs in @aoa;
my $col_num = @aoa;
# we need to decide on the column width. I will use an arbitrary width
+ and
# trim the items in each column to fit if required but you could check
+ the
# length of every item first and set the width to length(longest_item)
+ + 1
my $width = 8;
my $template = '%' . $width . 's';
for my $row ( 0 .. $max_rows -1 ) {
for my $col ( 0 .. $col_num -1 ) {
my $item = defined $aoa[$col][$row] ? $aoa[$col][$row] : '';
# for the colums to line up we need to pack them to the same w
+idth
# we will use printf to do this but you could use length and t
+he x op
# we set the $template to right justified, 8 chars wide column
+s
# we need to trim the $item to $width -1 chars max if we want
+discrete
# columns without items touching with no whitespace
$item = substr $item, 0, $width -1;
printf $template, $item;
}
print "\n";
}
__DATA__
one three Just
two four another
five Perl
Hacker
!
Note that if you set the $width to say 4 you get this:
one thr Jus
two fou ano
fiv Per
Hac
!
The truncation of the items maintains the discrete columns. Here is how to do a 'fit columns to data' which I just happened to have kicking around:
@array1 = qw(one two);
@array2 = qw(three four five);
@array3 = qw(Just another Perl Hacker !);
# make a 2D array
my @aoa = ( \@array1, \@array2, \@array3 );
# calculate max rows ( ie find array with largest number of members )
my $max_rows = 0;
for my $array_ref (@aoa) {
$max_rows = @$array_ref if @$array_ref > $max_rows;
}
# the number of columns is the number of array refs in @aoa;
my $col_num = @aoa;
my $width = get_col_width_templates(\@aoa, 1);
for my $row ( 0 .. $max_rows -1 ) {
for my $col ( 0 .. $col_num -1 ) {
my $item = defined $aoa[$col][$row] ? $aoa[$col][$row] : '';
# for the colums to line up we need to pack them to the same w
+idth
# we will use printf to do this but you could use length and t
+he x op
# we set the $template to right justified, 8 chars wide column
+s
# we need to trim the $item to $width -1 chars max if we want
+discrete
# columns without items touching with no whitespace
$item = substr $item, 0, $width -1;
printf $width->[$col], $item;
}
print "\n";
}
# get_col_width_templates( 2D_ARRAY_REF, MIN_WHITESPACE )
# takes 2D array ref and integer min whitespace to separate columns
# returns an array which contains a printf template such that the
# col width is just wide enough for the widest item in that column
# aka Excel fit column to data
sub get_col_width_templates {
my ($array_ref, $min_whitespace ) = @_;
$min_whitespace ||= 1;
my @width;
for my $row ( 0 .. $max_rows -1 ) {
for my $col ( 0 .. $col_num -1 ) {
my $item = defined $aoa[$col][$row] ? $aoa[$col][$row] : '
+';
$width[$col] = length($item) if length($item) > $width[$co
+l];
}
}
@width = map{ '%' . ( $_ + $min_whitespace) . 's' } @width;
return \@width;
}
__DATA__
one three Just
two four another
five Perl
Hacker
!
cheers
tachyon
s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print
|