可以使用条件拼接吗?

时间:2019-01-02 18:21:38

标签: perl

让我们考虑一下简单的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并更好地将结果推入新变量不是一种好习惯吗?

1 个答案:

答案 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;

将结果分配给与源相同的阵列没有问题,也没有循环管理或其他内务处理。