让我们考虑一下简单的Perl代码:
my @x = ( 1, 5, 9);
for my $i ( 0 .. $#x ) {
splice( @x, $i, 1 ) if ( $x[$i] >= 5 );
}
print "@x";
输出不正确,1 9
,但必须有1
如果我们使用-w
标志运行代码,则会显示警告
Use of uninitialized value within @x in numeric ge (>=) at splice.pl line 5.
因此,使用条件splice并更好地将结果推入新变量不是一种好习惯吗?
答案 0 :(得分:12)
问题不是您本身使用条件splice
,而是您的循环。最明显的问题(引起警告的一个问题)是,您即将耗尽数组的末尾。 for my $i ( 0 .. $#x )
在循环开始前 将迭代端点设置为$#x
,但是在拼接出一个或多个元素之后,数组的最后一个索引会变小。您可以使用C样式的for
循环而不是range样式的循环来解决此问题,但我不建议您继续阅读。
下一个问题是,在将元素从数组中剪接之后,您将循环与更高的$i
一起循环...但是由于您将元素从数组中剪接,所以您没有了下一个元素$x[$i]
中尚未显示,不是 $x[$i+1]
中。您说“输出正确,1 9
”,但是不应该删除9
,因为它大于5?您可以在redo
之后使用splice
来解决此问题,以再次遍历循环而无需增加$i
,但是我也不建议这样做。
因此 可以修复使用splice
的循环,使其正常工作,但结果会非常复杂。除非有令人信服的理由进行其他更改,否则我建议仅使用
@x = grep { $_ < 5 } @x;
将结果分配给与源相同的阵列没有问题,也没有循环管理或其他内务处理。