我需要在单个foreach循环中了解多个数组的正确语法。
在TCL中,我们可以在单个foreach循环中包含多个列表。但是如何用perl做到这一点?
#TCL eg:
foreach i $a j $e {
}
答案 0 :(得分:3)
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";
}
(我在这里使用的//
运算符是“ defined-OR”,与||
基本上相同,不同之处在于它作用于变量左侧是否具有定义的值,而不是是否具有真正的价值。)
答案 1 :(得分:2)
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'
每个列表中的值从头到尾依次使用,并且每个值仅使用一次。循环迭代的总数足够大,可以用完所有值列表中的所有值。如果值列表在每次迭代中都没有足够的元素用于其每个循环变量,则将空值用于缺少的元素。
在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'
答案 2 :(得分:2)
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
更灵活。
答案 3 :(得分:1)
对于不了解TCL的人,不清楚您想要什么,但我认为您需要以下条件:
---start of text---
test1
test2
test3
test4
---end is here---
答案 4 :(得分:1)
仅使用核心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";
}