2011-06-10 77 views
8

在流程可以多個列表迭代與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

回答

9

在Perl 5中,您可以使用該模塊List::MoreUtils。可以使用pairwise或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]"; 
} 
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_arrayrefList::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]) 

感謝亞歷克斯爲指出List::MoreUtils

6

與ZIP操作就可以實現你與計劃做什麼:

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

http://perlcabal.org/syn/S03.html#Zip_operators

+0

感謝tadzik。 Scheme的for-each概括爲1個或多個列表。可以將zip用於兩個以上的列表嗎? – dharmatech 2011-06-10 09:49:00

+2

它可以,雖然Rakudo目前只實現了兩個列表(已知的限制)。 – moritz 2011-06-10 13:03:55

+1

現在適用於任何數量的列表。 – raiph 2014-11-30 17:39:29

2

你可以只遍歷數組的索引,如果你確定它們是相同的尺寸:

foreach(0 .. $#array1) { 
    print $array1[$_] + $array2[$_], "\n"; 
} 
2

Algorithm::Loops提供了遍歷多個陣列一個MapCar函數(變體與不同大小的數組處理不同)。

10

在Perl 6中,Zip運算符是最好的選擇。如果你想獲得兩個值(而不是直接計算的總和),你可以使用它沒有加號:

for (10, 11, 12) Z (1, 2, 3) -> $a, $b { 
    say "$a and $b"; 
} 
+0

感謝mortiz!看到我的評論tadzik的答案。 – dharmatech 2011-06-10 10:06:50

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

但它不是在這種情況下流暢。如果兩個陣列都較短,會發生什麼?

1

只要這個問題很簡單,只要剛剛加入(/倍頻,分頻,...)和 數組沒有數組的數組,你也可以使用Hyper-運營商爲你的任務:

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

(當然這是一個Perl6答案)

,如果你不訪問法國的報價«»,你可以把它改寫爲

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