8

在 Scheme 中,您可以使用以下方法遍历多个列表for-each

> (for-each (lambda (a b) (display (+ a b)) (newline)) '(10 20 30) '(1 2 3))
11
22
33
> 

我知道在 Perl 中,您可以使用它for来迭代单个列表。像 Scheme 示例中那样迭代多个列表的好方法是什么?

我对 Perl 5 或 6 的答案很感兴趣。

4

8 回答 8

10

在 Perl 6 中,Zip 运算符是最好的选择。如果您想获得两个值(而不是直接计算总和),则可以不使用加号使用它:

for (10, 11, 12) Z (1, 2, 3) -> $a, $b {
    say "$a and $b";
}
于 2011-06-10T07:00:36.707 回答
9

在 Perl 5 中,您可以使用模块List::MoreUtils。使用成对或使用 each_array 返回的迭代器(可能需要两个以上的数组并行迭代)。

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]";
}
于 2011-06-10T00:59:17.027 回答
6

使用 Zip 运算符,您可以使用 Scheme 实现您正在做的事情:

> .say for (10, 20, 30) Z+ (1, 2, 3)
11
22
33

请参阅http://perlcabal.org/syn/S03.html#Zip_operators

于 2011-06-10T00:19:19.913 回答
2

如果您确定它们的大小相同,您可以迭代数组的索引:

foreach( 0 .. $#array1 ) {
  print $array1[$_] + $array2[$_], "\n";
}
于 2011-06-10T02:31:15.693 回答
2

Algorithm::Loops提供了一个 MapCar 函数,用于迭代多个数组(使用不同的变体处理大小不等的数组)。

于 2011-06-10T05:12:59.467 回答
1

一种方法是:

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])

使用each_arrayref来自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])

感谢 Alex 指出List::MoreUtils

于 2011-06-10T00:12:15.140 回答
1

只要问题很简单,只需添加 (/multiplying, 除...) 并且数组不是数组的数组,您也可以使用超级运算符来完成您的任务:

<1 2 3> «+» <10 20 30>

(当然这是 Perl6 的答案)

如果您无法访问法语引号«»,则可以将其重写为

<1 2 3> <<+>> <10 20 30>
于 2011-06-16T13:48:03.747 回答
0

一种解决方案(有很多可供选择)可能如下所示:

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);

我感觉到你在问关于foreach,它可能看起来像这样:

my @argle = (10, 20, 30);
my @bargle = (1, 2, 3);
for my $yin (@argle) {
    my $yang = shift @bargle;
    say $yin + $yang;
}

但在这种情况下并不那么顺利。如果任一数组较短会发生什么?

于 2011-06-10T07:47:58.030 回答