首页 > 解决方案 > 使用条件拼接可以吗?

问题描述

让我们考虑一下简单的 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.

那么,使用条件拼接并更好地将结果推送到新变量不是一个好习惯吗?

标签: perl

解决方案


问题不在于您使用条件splice本身,而在于您的循环。最明显的问题,也是导致您发出警告的问题,是您正在耗尽数组的末尾。for my $i ( 0 .. $#x )将迭代端点设置为循环开始$#x 之前,但是在拼接一个或多个元素后,数组的最后一个索引会更小。你可以使用 C 风格的for循环而不是范围风格的循环来解决这个问题,但我不推荐它——继续阅读。

下一个问题是,从数组中拼接出一个元素后,继续循环更高$i... . 你说“输出是正确的”,但不应该被删除,因为它超过 5?您可以使用after来解决此问题,以再次通过循环而不增加,但我也不建议这样做。$x[$i] $x[$i+1]1 99redosplice$i

因此,可以修复在适当位置使用的循环splice,使其正常工作,但结果会非常复杂。除非有令人信服的理由采取不同的做法,否则我建议您简单地使用

@x = grep { $_ < 5 } @x;

将结果分配给与源相同的数组没有问题,并且您无需进行循环管理或其他内务处理。


推荐阅读