Reputation: 31
I have a 2d perl array and I want to print each array vertically, however, I do not know the > size of the biggest array. How would I iterate through the matrix?
my @AoA = (
["abc", "def", 1, 2, 3],
["blah", "blah2", 2],
["hello", "world", "how", "are", "you", "doing?"],
);desired output:
abc blah hello
def blah2 world
1 2 how
2 null are
3 null you
null null doing
Upvotes: 1
Views: 933
Reputation: 126722
The best way is to scan your data twice: first to establish the maximum number of items in the columns and the maximum width of an item, and then to actually display the data.
This program demonstrates
use strict;
use warnings;
my @AoA = (
["abc", "def", 1, 2, 3],
["blah", "blah2", 2],
["hello", "world", "how", "are", "you", "doing?"],
);
my $maxrow;
my $maxwidth;
for my $col (@AoA) {
my $rows = $#$col;
$maxrow = $rows unless $maxrow and $maxrow >= $rows;
for my $item (@$col) {
my $width = length $item;
$maxwidth = $width unless $maxwidth and $maxwidth >= $width;
}
}
for my $row (0 .. $maxrow) {
my $line = join ' ', map sprintf('%-*s', $maxwidth, $_->[$row] // ''), @AoA;
print $line, "\n";
}
output
abc blah hello
def blah2 world
1 2 how
2 are
3 you
doing?
Update
It is much easier to provide your revised output, as there is no need to calculate the maximum field width.
use strict;
use warnings;
my @AoA = (
["abc", "def", 1, 2, 3],
["blah", "blah2", 2],
["hello", "world", "how", "are", "you", "doing?"],
);
my $maxrow;
for my $col (@AoA) {
$maxrow = $#$col unless $maxrow and $maxrow >= $#$col;
}
for my $row (0 .. $maxrow) {
print join(' ', map $_->[$row] // 'null', @AoA), "\n";
}
output
abc blah hello
def blah2 world
1 2 how
2 null are
3 null you
null null doing?
Upvotes: 2
Reputation: 17250
use List::Util qw(max);
# calculate length of longest sub-array
my $n = max map { scalar(@$_) } @AoA;
for (my $i = 0; $i < $n; ++$i) {
# the inner map{} pulls the $i'th element of each array,
# replacing it with 'null' if $i is beyond the end;
# each piece is then joined together with a space inbetween
print join(' ', map { $i < @$_ ? $_->[$i] : 'null' } @AoA) . "\n";
}
output
abc blah hello
def blah2 world
1 2 how
2 null are
3 null you
null null doing?
This is sort of dense and hard to read. You could make it more readable by splitting that print
line into several lines (one line to create a temporary array of all the $i
'th elements, another line to join them together, and another line to print the result).
Upvotes: 0