### Transpose a bi-dimensional array

 on Jul 21, 2003 at 11:18 UTC Need Help??

Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Greetings Monks,

I need to transpose a bi-dimentional array, so that rows become columns and vice-versa.

```my @matrix = (
[ qw(ab cd ef gh)],
[ qw(ij kl mn op)],
[ qw(qr st uv wx)]
);

# should become
my @transposed = (
[ qw(ab ij qr)],
[ qw(cd kl st)],
[ qw(ef mn uv)],
[ qw(gh op wx)]
);

I found Math::Matrix, which has a "transpose" method. However, it only works with numerical matrices, and since my matrices are mostly text, I was wondering if there are any general purpose methods (or modules) to achieve this goal.

Thanks

20030721 Edit by Corion: Changed title from 'Transpose a bi-dimentional array'

Replies are listed 'Best First'.
Re: Transpose a bi-dimensional array
by dbwiz (Curate) on Jul 21, 2003 at 11:24 UTC

tye has written a tool that should serve your purpose. Have a look at mapcar

```use mapcar;

my @matrix = (
[ qw(ab cd ef gh)],
[ qw(ij kl mn op)],
[ qw(qr st uv wx)]
);

my @transposed = mapcar {[@_]} @matrix;

print join( "  ", @\$_), \$/ for @transposed;

__END__
ab  ij  qr
cd  kl  st
ef  mn  uv
gh  op  wx
Update
mapcar is now a function in tye's Algorithm::Loops.

The above example would becpme:

```
use Algorithm::Loops qw(MapCar);

my @matrix = (
[ qw(ab cd ef gh)],
[ qw(ij kl mn op)],
[ qw(qr st uv wx)]
);

my @transposed = MapCar {[@_]} @matrix;

print join( "  ", @\$_), \$/ for @transposed;

With exactly the same result.

Re: Transpose a bi-dimensional array
by edan (Curate) on Jul 21, 2003 at 11:28 UTC

Or, you could just peek in the source of Math::Matrix, nick the transpose() method, un-OO-ify it, and ... voila!

```#!perl -l

my @matrix = (
[ qw(ab cd ef gh)],
[ qw(ij kl mn op)],
[ qw(qr st uv wx)]
);

my \$transposed = transpose(\@matrix);
local \$" = ",";
print "@\$_" for @\$transposed;

sub transpose {
my \$matrix = shift;
my @result;
my \$m;

for my \$col (@{\$matrix->[0]}) {
push @result, [];
}
for my \$row (@{\$matrix}) {
\$m=0;
for my \$col (@{\$row}) {
push(@{\$result[\$m++]}, \$col);
}
}

return \@result;
}

Disclaimer: not my coding style! I just modified existing code to make a point (Use the Source, Luke)

--
3dan
Re: Transpose a bi-dimensional array
by Abigail-II (Bishop) on Jul 21, 2003 at 12:35 UTC
A totally different way than already presented using tie:
```package Tie::Transpose;

use strict;
use warnings;

sub TIEHASH  {bless \$_ [1] => \$_ [0]}
sub FETCH    {my (\$y, \$x) = split /\$;/ => \$_ [1]; \$_ [0] [\$x] [\$y]}
sub STORE    {die}

package main;

my \$matrix = [[qw /ab cd ef/],
[qw /gh ij kl/],
[qw /mn op qr/],
[qw /st uv wx/]];

tie my %trans => 'Tie::Transpose', \$matrix;

print \$trans {0, 0}, "\n";
print \$trans {0, 1}, "\n";
print \$trans {0, 2}, "\n";
print \$trans {0, 3}, "\n";
__END__
ab
gh
mn
st

You may want to work out some details before putting this in production code.

Abigail

Re: Transpose a bi-dimensional array
by broquaint (Abbot) on Jul 21, 2003 at 11:31 UTC
With a liberal use of map then we get the following code
```use Data::Dumper;

my @matrix = (
[ qw(ab cd ef gh)],
[ qw(ij kl mn op)],
[ qw(qr st uv wx)]
);

my @transposed = map {
my \$i = \$_;
[ map \$matrix[\$_]->[\$i], 0 .. \$#matrix ]
} 0 .. \$#{\$matrix[0]};

print Dumper(\@transposed);

__output__

\$VAR1 = [
[
'ab',
'ij',
'qr'
],
[
'cd',
'kl',
'st'
],
[
'ef',
'mn',
'uv'
],
[
'gh',
'op',
'wx'
]
];
Not as elegant as dbwiz's solution, but effective nonetheless.
HTH

_________
broquaint

Re: Transpose a bi-dimensional array
by jmcnamara (Monsignor) on Jul 21, 2003 at 11:29 UTC

Here is one way:
```    #!/usr/bin/perl -wl

use strict;
use Data::Dumper;

my @matrix = (
[ qw(ab cd ef gh)],
[ qw(ij kl mn op)],
[ qw(qr st uv wx)]
);

my @transpose;
for my \$aref (@matrix) {
my \$i = 0;
push @{\$transpose[\$i++]}, \$_ for @\$aref;
}

print Dumper(@matrix);
print Dumper(@transpose);

__END__

--
John.

Hi John, How to print the data to the specific file instead of in terminal? Thanks Anil

Create A New User
Node Status?
node history
Node Type: perlquestion [id://276221]
Approved by broquaint
Front-paged by cchampion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others having an uproarious good time at the Monastery: (6)
As of 2020-10-29 07:38 GMT
Sections?
Information?
Find Nodes?
Leftovers?
Voting Booth?
My favourite web site is:

Results (269 votes). Check out past polls.

Notices?