Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked
 
PerlMonks  

Transpose a bi-dimensional array

by Anonymous Monk
on Jul 21, 2003 at 11:18 UTC ( #276221=perlquestion: print w/replies, xml ) 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

Log In?
Username:
Password:

What's my password?
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 cooling their heels in the Monastery: (3)
As of 2020-05-25 05:05 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    If programming languages were movie genres, Perl would be:















    Results (143 votes). Check out past polls.

    Notices?