for with multiple arrays
In Scheme you can iterate over multiple lists in with for-each
:
> (for-each (lambda (a b) (display (+ a b)) (newline)) '(10 20 30) '(1 2 3))
11
22
33
>
I know that in Perl you can use for
to iterate over a single list. What's a good way to ite开发者_StackOverflow中文版rate over multiple lists as in the Scheme example?
I'm interested in answers for Perl 5 or 6.
In Perl 6, the Zip operator is the nicest choice. If you want to get both values (and not compute the sum directly), you can use it without the plus sign:
for (10, 11, 12) Z (1, 2, 3) -> $a, $b {
say "$a and $b";
}
In Perl 5 you can use the module List::MoreUtils. Either with pairwise or with the iterator returned by each_array (which can take more than two arrays to iterate through in parallel).
use 5.12.0;
use List::MoreUtils qw(pairwise each_array);
my @one = qw(a b c d e);
my @two = qw(q w e r t);
my @three = pairwise {"$a:$b"} @one, @two;
say join(" ", @three);
my $it = each_array(@one, @two);
while (my @elems = $it->()) {
say "$elems[0] and $elems[1]";
}
With the Zip operator you can achieve what you're doing with Scheme:
> .say for (10, 20, 30) Z+ (1, 2, 3)
11
22
33
See http://perlcabal.org/syn/S03.html#Zip_operators
You could just iterate over the indices of the arrays, if you're sure they're the same size:
foreach( 0 .. $#array1 ) {
print $array1[$_] + $array2[$_], "\n";
}
Algorithm::Loops offers a MapCar function for iterating over multiple arrays (with variants that deal differently with unequally sized arrays).
One way is:
sub for_each
{
my $proc = shift ;
my $len = @{$_[0]} ;
for ( my $i = 0 ; $i < $len ; $i++ )
{
my @args = map $_->[$i] , @_ ;
&$proc ( @args ) ;
}
}
for_each sub { say $_[0] + $_[1] } , ([10,20,30],[1,2,3])
Using each_arrayref
from List::MoreUtils
:
sub for_each
{
my $proc = shift ;
my $it = each_arrayref ( @_ ) ;
while ( my @elts = $it->() ) { &$proc ( @elts ) } ;
}
for_each sub { say $_[0] + $_[1] } , ([10,20,30],[1,2,3])
Thanks to Alex for pointing out List::MoreUtils
.
As long as the question is as simple as just adding (/multiplying, dividing,…) and the Arrays are no Arrays of Arrays, you also could use the hyper-operators for your task:
<1 2 3> «+» <10 20 30>
(of course this is a Perl6 answer)
if you don't have access to the French quotes «»
, you could rewrite it as
<1 2 3> <<+>> <10 20 30>
One solution (there are many to choose from) might look like this:
my @argle = (10, 20, 30);
my @bargle = (1, 2, 3);
do {
my $yin = shift @argle;
my $yang = shift @bargle;
say $yin + $yang;
} while (@argle && @bargle);
I sense that you are asking about foreach
, which might look like this:
my @argle = (10, 20, 30);
my @bargle = (1, 2, 3);
for my $yin (@argle) {
my $yang = shift @bargle;
say $yin + $yang;
}
But it is not as smooth in this case. What happens if either array is shorter?
精彩评论