【问题标题】:What is the 'best' way to delete multiple non-sequential elements in a Perl array?删除 Perl 数组中多个非顺序元素的“最佳”方法是什么?
【发布时间】:2014-08-16 08:43:36
【问题描述】:

在执行脚本时,我需要删除数组的多个元素(这些元素不是连续的)。我将在执行脚本时获取我的数组和索引。

例如:

我可能会得到一个数组和索引列表,如下所示:

my @array = qw(one two three four five six seven eight nine);

my @indexes = ( 2, 5, 7 );

我有以下子程序可以做到这一点:

sub splicen {
    my $count     = 0;
    my $array_ref = shift @_;

    croak "Not an ARRAY ref $array_ref in $0 \n"
        if ref $array_ref ne 'ARRAY';

    for (@_) {
        my $index = $_ - $count;
        splice @{$array_ref}, $index, 1;
        $count++;
    }

    return $array_ref;
}

如果我像下面这样调用我的子程序:

splicen(\@array , @indexes);

这对我有用,但是:

有没有更好的方法来做到这一点?

【问题讨论】:

  • 提供示例输入和输出,使问题(和目标)更清晰。如果给定的代码不能产生预期的结果,也要解释一下。

标签: arrays perl


【解决方案1】:

如果改为从数组末尾拼接,则不必维护偏移量$count

sub delete_elements {
    my ( $array_ref, @indices ) = @_;

    # Remove indexes from end of the array first
    for ( sort { $b <=> $a } @indices ) {
        splice @$array_ref, $_, 1;
    }
}

【讨论】:

  • 只是为了确定,您应该自己对 @indices 数组进行排序,或者至少记录您期望排序后的数组。
【解决方案2】:

另一种思考方式是构建一个新数组而不是修改原始数组:

my @array   = qw(one two three four five size seven eight nine);
my @indexes = (2, 5, 7);
my %indexes = map { $_ => 1 } @indexes;
my @kept    = map { $array[$_] } grep { ! exists $indexes{$_} } 0 .. $#array;

【讨论】:

  • 这花费了我一个额外的哈希和数组@FMc
  • 如果原始数组中有弱引用,这也会破坏(即加强)弱引用。也许是一个小问题,但在此之前已经被我咬过。原始数组上的splice 不会以这种方式干扰其余元素。
猜你喜欢
  • 2011-04-09
  • 2010-10-11
  • 2010-09-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-15
  • 2019-09-01
  • 1970-01-01
相关资源
最近更新 更多