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

时间:2016-03-15 04:40:05

标签: 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;
}

3 个答案:

答案 0 :(得分:2)

你不需要array slice之外的任何东西,所以我不会为此创建一个sub。

my @wanted = @array[@indices];

如果您正在使用数组引用,则适用相同的配方:

my @wanted = @{$array}[@$indices];

答案 1 :(得分:1)

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

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

最终@arr_filt包含除@arr_orig以外索引的@ind_toss元素。

请参阅ysththis post的解决方案,以便通过另一个数组过滤数组元素。

将其包裹在子中并运行。包含要排除的索引的数组为@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)] ];
}

打印

a b c d e

备注

Oleg V. Volkov在评论中暗示,来自子网的return也可以写为

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

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

答案 2 :(得分:0)

只是为了清理一下zdim的答案(无论如何都是正确的):

sub filter_array_by_index {
    my ( $rarr, $rind ) = @_;
    my %ref_index = map { $_ => 1 } @ind_toss;
    my @indices = grep { !$ref_index{$_} } (0..$#$rarr);

    return @{$rarr}[@indices];
}