我在线观看,似乎每个人都说它们可以互换使用。但是,当我遍历我的数组时,它给了我不同的结果。
我有一个约数组。 60个字符串元素,并过滤掉另一个数组中匹配的任何内容。但是当我使用foreach
时,它只看到了45个元素的数组,所以当我打印出最终结果时,它并没有过滤掉所有内容。
只有当我使用for
它才能按我的意愿工作时。这背后的原因是什么?
我设法解决了这个问题,现在我只是想了解它的工作方式。谢谢!
编辑:所以我没有提供任何例子,所以这就是我所做的:
my $i = 0;
foreach my $item (@array){
print "\n$i : $item";
foreach my $exclude_item (@exclude){
chomp $exclude_item;
if ($exclude_item eq $item){
print "\nDEBUG: Removing $item";
splice @array, $i, 1;
}
}
$i++;
}
上面没有给我一份@array
的完整清单,所以当我打印出最终结果时,里面的元素应该被过滤掉。
所以我尝试了这个(按照我的意愿工作):
for (my $i=0; $i < scalar @array; $i++){
print "\n$i : $array[$i]";
foreach my $exclude_item (@exclude){
chomp $exclude_item;
if ($exclude_item eq $array[$i]){
print "\nDEBUG: Removing $array[$i]";
splice @array, $i, 1;
}
}
}
只是附加信息,@array
是通过搜索多个文件夹中的子目录列表创建的。 @array
可能包含重复项。
答案 0 :(得分:14)
# Foreach loop \
foreach my $item (@array) > same \
for my $item (@array) / \
> different
# Augmented while loop \ /
for (my $i=0; $i < scalar @array; $i++) > same /
foreach (my $i=0; $i < scalar @array; $i++) /
您不得修改迭代的数组。来自perlsyn,
如果LIST的任何部分是数组,如果在循环体内添加或删除元素,
foreach
将会非常混乱,例如使用splice
。所以不要这样做。
因此,
foreach (@array){
...
splice @array, $i, 1; # XXX Error
...
}
请注意,您可以安全地修改要迭代的数组元素。
foreach (@array){
$_ = uc($_); # ok
}
最后,一个更好的解决方案:
chomp(@exclude);
my %exclude = map { $_ => 1 } @exclude;
@array = grep { !$exclude{$_} } @array;
除了更简单之外,它的扩展性要好得多 [1] 。
答案 1 :(得分:6)
当人们说他们被互换使用时,他们意味着foreach
关键字只是for
关键字的同义词。这意味着以下两行意味着完全相同:
foreach my $item (@array) {...}
for my $item (@array) {...}
为避免疑义,我会忽略foreach
关键字,并仅使用下面的for
。
如您所见,以下两行的行为不同:
for my $item (@array) {...}
for (my $i = 0; $i < scalar @array; $i++) {...}
manual建议不要在第一行的循环体中添加或删除@array
中的元素,并且不会说出结果是什么。
如果第二行的循环体在@array
之前或之前删除了$i
中的元素,则结果将是跳过新位置$i
的元素。如果它在$i
之前或之前添加了一个元素,那么结果将是第二次循环看到旧位置$i
的元素。