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

Dear Masters,
Assume that these three arrays are of the same size, and they maybe greater or lesser than 3:
my @arr1 = qw( A B C ); my @arr2 = qw(foo bar qux); my @arr3 = (1, 2, 3 );
Is there a fast way to construct this AoA from them:
# Namely, they are symmetrical... my @all = ( ['A', 'foo', 1], ['B', 'bar', 2], ['C', 'qux', 3] );


---
neversaint and everlastingly indebted.......

Replies are listed 'Best First'.
Re: Creating Symmetrical AoA from some Arrays
by GrandFather (Saint) on Nov 25, 2005 at 02:59 UTC
    use strict; use warnings; use Data::Dumper; my @arr1 = qw( A B C ); my @arr2 = qw(foo bar qux); my @arr3 = (1, 2, 3 ); my @all; for my $source (\@arr1, \@arr2, \@arr3) { push @{$all[$_]}, $source->[$_] for 0..@$source-1; } print Dumper (\@all);

    DWIM is Perl's answer to Gödel
Re: Creating Symmetrical AoA from some Arrays
by monkfan (Curate) on Nov 25, 2005 at 02:52 UTC
    my @all = map {[ $arr1[$_], $arr2[$_], $arr3[$_] ]} (0..@arr-1);
    Update: typo corrected..thanks to ikegami's notice.

    Regards,
    Edward

      @pat-1
      should be
      @arr1-1
      and can be written as
      $#arr1

      The following should be a bit faster and much more memory efficient (but not as neat):

      my @all; push(@all, [ $arr1[$_], $arr2[$_], $arr3[$_] ]) foreach 0..$#arr1;

      Even faster?

      my @all; $#all = $#arr1; $all[$_] = [ $arr1[$_], $arr2[$_], $arr3[$_] ] foreach 0..$#arr1;
Re: Creating Symmetrical AoA from some Arrays
by kulls (Hermit) on Nov 25, 2005 at 05:53 UTC
    Hi,
    I just tried with  Math::Matrix module, and i got it as simple .
    use Math::Matrix; use Data::Dumper; my @arr1 = qw( A B C ); my @arr2 = qw(foo bar qux); my @arr3 = (1, 2, 3 ); $a = new Math::Matrix( \@arr1,\@arr2,\@arr3); $all = $a->transpose($a); print STDERR Dumper($all); __OUTPUT__ $VAR1 = bless( [ ['A','foo',1], ['B','bar',2], ['C','qux',3]], 'Math::Matrix' );

    I guess i'm correct.
    -kulls
Re: Creating Symmetrical AoA from some Arrays
by davidrw (Prior) on Nov 25, 2005 at 02:48 UTC
    Could create
    my @tmp = ( \@arr1, \@arr2, \@arr3 );
    and transpose it ...
    my @all; foreach my $x (0 .. $#tmp){ foreach my $y (0 .. $#tmp){ $all[$x]->[$y] = $tmp[$y]->[$x]; } } # or my @all = map { my $x = $_ ; [ map { $tmp[$_]->[$x] } 0 .. $#tmp ] } 0 + .. $#tmp; # or do: my @all = ( \@arr1, \@arr2, \@arr3 ); and then in-place swap (i,j) with (j,i) .. but this will modify the o +riginal @arrX arrays.
Re: Creating Symmetrical AoA from some Arrays
by pg (Canon) on Nov 25, 2005 at 04:47 UTC

    Or you can make it more generic with recursive code:

    use Data::Dumper; use strict; use warnings; my $arr1 = ['A', 'B', 'C']; my $arr2 = ['foo', 'bar', 'qux']; my $arr3 = [1, 2, 3]; my $arr4 = ['apple', 'banana', 'pear']; print Dumper(mix($arr1, $arr2, $arr3, $arr4)); sub mix { if (@_ > 2) { return mix($_[0], mix(@_[1..$#_])); } else { my @a = map {[$_[0]->[$_], (ref($_[1]->[0]) eq 'ARRAY') ? @{$_ +[1]->[$_]} : $_[1]->[$_]]} (0 .. @{$_[0]} - 1); return \@a; } }

    Which prints:

    $VAR1 = [ [ 'A', 'foo', 1, 'apple' ], [ 'B', 'bar', 2, 'banana' ], [ 'C', 'qux', 3, 'pear' ] ];
Re: Creating Symmetrical AoA from some Arrays
by tilly (Archbishop) on Nov 25, 2005 at 02:54 UTC
    What do you mean by fast?
    my @arr1 = qw( A B C ); my @arr2 = qw(foo bar qux); my @arr3 = (1, 2, 3 ); my @all = transpose(\@arr1, \@arr2, \@arr3); sub transpose { my (@a_o_a) = @_; my @ans; for my $i (0..$#a_o_a) { my $a = $a_o_a[$i]; for my $j (0..$#$a) { $ans[$j][$i] = $a->[$j]; } } return @ans; }
    This will work for any number of arrays, even if they aren't symmetrical.