我需要知道在一个单一的foreach循环多个阵列正确的语法。
在TCL,我们可以在一个单一的foreach循环多个列表。但如何用Perl做呢?
#TCL eg:
foreach i $a j $e {
}
而TCL的语法是不明确的,所以我去的来源,即tclsh
:
% set a { 1 2 3 4 }
1 2 3 4
% set e { 4 5 6 7 0 9 }
4 5 6 7 8 9
% foreach i $a j $e { puts "'$i' '$j'" }
'1' '4'
'2' '5'
'3' '6'
'4' '7'
'' '0'
'' '9'
在每个list中的值,以便使用从第一个到最后,每个值使用一次。循环迭代的总数大到足以从所有值列表使用的所有值。如果一个值的列表不包含每个在每个迭代的循环变量的足够的元素,空值用于缺少的元素。
在Perl“空”元素undef
,所以我想最接近翻译成Perl是:
#!/usr/bin/perl
use strict;
use warnings;
use List::Util qw(max);
my @a = (1, 2, 3, 4);
my @e = (4, 5, 6, 7, 0, 9);
my $max_index = max($#a, $#e);
foreach my $index (0..$max_index) {
my $i = $a[$index] // '';
my $j = $e[$index] // '';
# your "TCL" loop code goes here...
print "$index '$i' '$j'\n";
}
exit 0;
测试输出:
$ perl dummy.pl
0 '1' '4'
1 '2' '5'
2 '3' '6'
3 '4' '7'
4 '' '0'
5 '' '9'
所述List::MoreUtils模块的当前版本提供一个zip_unflatten
命令将两个(或更多)阵列结合到含于每个列表的第一个元素,则第二,等等的阵列的引用单个阵列:
#!/usr/bin/env perl
use strict;
use warnings;
use 5.010;
use List::MoreUtils 'zip_unflatten';
my @a = 1 .. 4;
my @e = 5 .. 9;
my @z = zip_unflatten(@a, @e);
for my $pair (@z) {
my $i = $pair->[0] // '-';
my $j = $pair->[1] // '-';
say "$i\t$j";
}
(我在这里使用的//
运营商“定义-OR”,这是基本相同||
,但它的工作原理上的变量,其左侧是否有一个定义的值,而不是它是否有一个真正的价值。)
该List::UtilsBy功能zip_by
可能是这个任务非常有用。不幸的是声明在当前foreach循环迭代多变量没有什么好办法,所以我们使用arrayrefs。
use strict;
use warnings;
use List::UtilsBy 'zip_by';
my @arr1 = ...;
my @arr2 = ...;
foreach my $zipped (zip_by { [@_] } \@arr1, \@arr2) {
my ($i, $j) = @$zipped;
...
}
该List::SomeUtils zip
功能做到这一点相同的任务更简洁,但一个尴尬的原型要求阵列,其中zip_by
更加灵活。
的人谁不知道TCL,目前还不清楚你想要什么,但我想你想的以下内容:
for my $i (0..$#foos) {
my $foo = $foos[$i];
my $bar = $bars[$i];
...
}
只需Perl核心,这里还有使用shift
的选择,但要注意,这种方法修改(空箱)的阵列,因此使用它们的副本,如果它的事项:
#!/usr/bin/env perl
use strict;
use warnings;
use 5.010;
my @a = 1 .. 4;
my @e = 5 .. 9;
while (@a || @e) {
my $i = shift @a // '-';
my $j = shift @e // '-';
say "$i\t$j";
}