在Perl中通过索引从数组中排除元素的最佳方法是什么?

use*_*739 5 arrays perl

我使用以下代码来排除@{$x}索引中的元素@{$index}.但我不确定它是实现此功能的最有效方式.有没有人有更好的方法.

sub arrayexclude {
    my $x = shift;
    my $index = shift;

    my @keep_index = (0 .. (scalar(@{$x})-1));

    delete @keep_index[@{$index}];

    my $result=[];

    for my $i (@keep_index) {
        if(defined $i) {
            push @{$result}, @{$x}[$i];
        }
    }
    return $result;
}
Run Code Online (Sandbox Code Playgroud)

zdi*_*dim 1

准备一个哈希以便有效地识别索引,然后用它索引到原始数组中。

my %ref_index;
@ref_index{ @ind_toss } = ();    
@arr_filt = @arr_orig[ grep { !exists $ref_index{$_} } (0..$#arr_orig) ];
Run Code Online (Sandbox Code Playgroud)

Final包含at 索引中除 之外@arr_filt的元素。@arr_orig@ind_toss

一般情况下,请参阅ysth这篇文章中通过另一个数组过滤数组元素的解决方案。


将其包裹在潜艇中并运行。具有要排除的索引的数组是@ind_toss,原始数组是@arr_orig

use warnings;
use strict;

my @ind_toss = (1, 4, 5);
my @arr_orig = ('a', '1', 'b', 'c', '2', '6', 'd', 'e');

my @filtered = @{ filter_array_by_index(\@arr_orig, \@ind_toss) };

print "@filtered" . "\n";    

sub filter_array_by_index {
    my ($rarr, $rind) = @_;    
    my %ref_index;
    @ref_index{ @$rind } = (); 
    return [ @$rarr[grep { !exists $ref_index{$_} } (0..$#$rarr)] ];
}
Run Code Online (Sandbox Code Playgroud)

印刷

my %ref_index;
@ref_index{ @ind_toss } = ();    
@arr_filt = @arr_orig[ grep { !exists $ref_index{$_} } (0..$#arr_orig) ];
Run Code Online (Sandbox Code Playgroud)

笔记

正如Oleg V. Volkov的评论所暗示的,来自returnsub 的也可以写成

return [ map { !exists $ref_index{$_} ? $rarr->[$_] : ()  } (0..$#$rarr) ];
Run Code Online (Sandbox Code Playgroud)

grep这避免了通过切片构建列表,而是有条件地索引到数组中。