user3329763
user3329763

Reputation: 31

How to print each array in 2d array vertically in perl

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

Answers (2)

Borodin
Borodin

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

TypeIA
TypeIA

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

Related Questions