Dr.Avocado has asked for the wisdom of the Perl Monks concerning the following question:

Dear Perl experts,

I have three arrays that each have x values in them (x can change). How can I make a script that uses matching values in each array, as in:
print "@array1[1], @array2[1], @array3[1]\n" print "@array1[2], @array2[2], @array3[2]\n" print "@array1[3], @array2[3], @array3[3]\n" ... ... ... print "@array1[x], @array2[x], @array3[x]\n"
where x is the number of elements in the arrays? I would appreciate any help.

Replies are listed 'Best First'.
Re: Matching Values in Arrays
by FunkyMonk (Bishop) on Aug 07, 2007 at 16:07 UTC
    Assuming all the arrays have the same length...

    print "$array1[$_], $array2[$_], $array3[$_]\n" for 0 .. $#array1;

    See perldata for a description of $#array which I presume is the bit you were struggling with

Re: Matching Values in Arrays
by Corion (Patriarch) on Aug 07, 2007 at 16:10 UTC

    You want a hash or an array to store references to your three arrays. http://perl.plover.com/varvarname.html has a better explanation of how to approach your problem than I can ever write.

    The short of it is that you want:

    my @arrays = (\@array1, \@array2, \@array3); for my $row (0..$#${ $arrays[0] }) { print "$row: "; for my $array (@arrays) { print $array->[$row], ";"; }; print "\n"; };

    Also see tye's References Quick Reference for more information about references

      Your code is not correct. You are trying to print a SCALAR ref that does not exist. Here is what I have:
      use strict; use warnings; local $, = "\t"; my @array1= qw(Bob smith); my @array2= qw(Jen smith); print (@array1, @array2); print "\n"; my @arrays = (\@array1, \@array2); for my $row (0..$#{ $arrays[0] }) { print "$row: "; for my $array (@arrays) { print $array->[$row], ";"; }; print "\n"; }; __OUTPUT__ Bob smith Jen smith 0: Bob ;Jen ; 1: smith ;smith ;
        Another version:
        use strict; use warnings; local $, = "\t"; my @array1= qw(Ben bobby smith); my @array2= qw(Ben laurie smith); print (@array1, @array2); print "\n"; my @arrays = (\@array1, \@array2); use Data::Dumper; print Dumper ($arrays[0]),"\n"; for my $row (0..$#{ $arrays[0] }) { print "ROW:$row: "; for my $array (@arrays) { print $array->[$row], ";"; if ($array1[$row] eq $array2[$row]) { print $array->[$row], ";"; print qq{ \nElements $row are equal with values of \n$array1[$row] and $array2[$row] in \n$@arrays\n }; last; } }; print "\n"; };
Re: Matching Values in Arrays
by mjscott2702 (Pilgrim) on Aug 07, 2007 at 18:55 UTC
    Do you want to print only "rows" where the values in each array are identical, or just side-by-side?
    If just side-by-side, the code from FunkyMonk is just what you need, and easy to understand.
    If you need only rows where the values are the same, do something like:
    for (0 .. $#array1) { if ($array1[$_] eq $array2[$_] && $array1[$_] eq $array3[$_]) { print "$array1[$_], $array2[$_], $array3[$_]\n"; } }
    Note that the array indices start at 0, and $#array1 means the index of the last element in @array1. This assumes you haven't modified the value of a Perl special variable $[, which is discouraged.
    If the values are numeric, you should use == instead of eq. If they are mixed - well, that's a more complicated issue, doing numerical comparisons on strings can cause unexpected results