4

如何使用 perl 拼接参考数组?我正在尝试从函数中使用的引用数组中删除某些元素。

    &removeELement(@spliceArray);

    sub removeELement
    {
        my $ref_to_spliceArray = shift;

        foreach my $i (0 .. $#$ref_to_spliceArray)
        {
              if($ref_to_spliceArray->[$i] == /failed/)
              {
                    splice $ref_to_spliceArray->[$i],1; # this syntax does not work...
              }
        }
    }
4

4 回答 4

2

您可以通过对代码进行一些更改来获得所需的行为。

  • 如果删除数组的一个元素,下一个元素的索引现在与旧值的索引相同。你不能盲目地迭代0 .. $#ref_to_spliceArray
  • 正则表达式绑定运算符 is=~和 not ==
  • 尝试与未定义值匹配的正则表达式可能会触发警告。
  • 将数组传递给splice,而不是数组的单个元素。

下面的代码修复了这些问题。

sub removeElement
{
  my $ref_to_spliceArray = shift;

  my $i = 0;
  while ($i <= $#$ref_to_spliceArray)
  {
    if (defined $ref_to_spliceArray->[$i]
          && $ref_to_spliceArray->[$i] =~ /failed/)
    {
      splice @$ref_to_spliceArray, $i, 1;
    }
    else {
      ++$i;
    }
  }
}

将您的呼叫修改为

&removeElement(\@spliceArray);

请注意,这种语法在现代人眼中会显得过时。考虑对整个数组进行操作,而不是一次偷看和戳一个元素。在这种简单的情况下,您无需费心定义另一个 sub。

@spliceArray = grep !(defined && /failed/), @spliceArray;

也就是说,@spliceArray应该只包含那些与正则表达式不匹配的元素。该defined检查可防止警告可能存在于 中的未定义值@spliceArray

于 2012-05-26T19:43:42.510 回答
0

尝试从您正在迭代的列表中删除元素通常是一个坏主意。尝试使用grep创建一个仅包含您想要保留的元素的新列表,并将其分配回原始参考。

sub removeElement {
    my $ref_to_Array = shift;

    @$ref_to_Array = grep { ! /failed/ } @$ref_to_array;
}

&removeElement(\@someArray);

请注意,您需要将对数组的引用传递给函数。

splice顺便说一句,您可能正在寻找的电话是

splice @$ref_to_spliceArray, $i, 1
于 2012-05-26T17:35:28.250 回答
0

为了splice正确使用,我建议看一下splice手册页

如果使用引用,只需取消引用它:@$aref而不是$aref.

为了解决手头的问题,请考虑grep改用。这是一个使用 Windows(双引号!)命令行的示例:

perl -lwe "$x = [qw/a b failed d/]; print for grep ! m/failed/, @$x"

还有一件事:将正则表达式与=~and !~, not一起使用==

而你正在使用strict,不是吗?永远use strict,永远!

于 2012-05-26T17:28:35.550 回答
0

你可以简单地使用grep这个:

my @array = qw/foo bar baz qux/;
@array = grep { ! m/baz/ } @array;
# @array now contains foo bar qux

您的代码有几个错误:

  • ==不是一回事=~
  • 您没有指定拼接的偏移量和长度(例如splice $@aray, $i, 1
  • 从数组中删除拼接和元素后,索引$i将不正确,因为您从数组中删除了和项目,并且您将针对不存在的元素检查数组。
于 2012-05-26T17:28:38.897 回答