让我们考虑一下简单的Perl代码:
my @x = ( 1, 5, 9);
for my $i ( 0 .. $#x ) {
splice( @x, $i, 1 ) if ( $x[$i] >= 5 );
}
print "@x";
Run Code Online (Sandbox Code Playgroud)
输出不正确,1 9但必须有1
如果我们使用-wflag 运行代码,则会打印警告
Use of uninitialized value within @x in numeric ge (>=) at splice.pl line 5.
Run Code Online (Sandbox Code Playgroud)
那么,使用条件拼接并且更好地将结果推入新变量并不是一个好习惯吗?
hob*_*bbs 12
问题不在于您使用条件splice本身,而是您的循环.最明显的问题是导致警告的问题,那就是你正在运行数组的末尾.for my $i ( 0 .. $#x )将迭代端点设置为$#x 在循环开始之前,但在将一个或多个元素拼接出来之后,该数组的最后一个索引将更小.您可以使用C风格的for循环来修复它,而不是范围风格的循环,但我不推荐它 - 继续阅读.
接下来的问题是,在将一个元素拼接出数组之后,继续使用$i一个更高的循环...但是因为你将一个元素拼接出数组,你还没有看到的下一个元素是$x[$i],而不是 $x[$i+1].你说"输出是正确的1 9",但不应该9删除,因为它超过5?您可以使用redoafter splice来修复此问题,无需递增即可再次执行循环$i,但我也不建议这样做.
因此,它是可以修复你的循环,它使用splice的地方,以便在将正常工作,但结果将是非常复杂的.除非有令人信服的理由以不同方式进行,否则我建议使用简单
@x = grep { $_ < 5 } @x;
Run Code Online (Sandbox Code Playgroud)
将结果分配给与源相同的数组没有问题,并且没有循环管理或其他内务处理.