【问题标题】:What is the best way to exclude elements from an array by indexes in Perl?在 Perl 中通过索引从数组中排除元素的最佳方法是什么?
【发布时间】:2016-06-25 14:35:29
【问题描述】:

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

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;
}

【问题讨论】:

  • 作为一个补充说明,0 .. (scalar(@{$x})-1) 更容易写成0 .. $#$x,或者如果你更喜欢0 .. $#{$x}
  • $#foo 经常被误用,如果你给它加 1,你就做错了......但如果你在数组的索引范围内,或者在谈论最后一个索引,正是你想要的。

标签: arrays perl


【解决方案1】:

除了array slice,你不需要任何东西,所以我会避免为此创建一个子。

my @wanted = @array[@indices];

如果您使用的是数组引用,则同样适用:

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

【讨论】:

  • 我相信 OP 需要在这些索引处排除元素。
【解决方案2】:

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

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

最终的@arr_filt 包含@arr_orig 的元素,而不是@ind_toss 中的索引。

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


将它包装在一个子中并运行。要排除的索引数组是@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

备注

来自子的return,正如Oleg V. Volkov在评论中暗示的那样,也可以写成

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

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

【讨论】:

  • 其实这个打印的是6
  • @ChatterOne 已修复,非常感谢。来自不同版本的错字:(
  • 为什么grep + slice 如果你可以马上map 并摆脱临时索引数组?
【解决方案3】:

只是为了清理一下 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];
}

【讨论】:

    猜你喜欢
    • 2010-09-15
    • 1970-01-01
    • 1970-01-01
    • 2011-04-09
    • 1970-01-01
    • 2019-09-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-11
    相关资源
    最近更新 更多