2016-03-15 8 views
5

Używam następującego kodu, aby wykluczyć elementy z @{$x} w indeksach w @{$index}. Ale nie jestem pewien, czy jest to najskuteczniejszy sposób realizacji tej funkcji. Czy ktokolwiek ma lepszy sposób?Jaki jest najlepszy sposób na wykluczenie elementów z tablicy według indeksów w Perlu?

+1

Bardziej na marginesie: '0 .. (skalar (@ {$ x}) - 1)' jest znacznie łatwiejsze do zapisania '0 .. $ # $ x' lub jeśli wolisz' 0 .. $ # {$ x} '. – hobbs

+0

'$ # foo' jest często nadużywane, a jeśli dodajesz 1 do niego, robisz coś nie tak ... ale jeśli masz do czynienia z wskaźnikami tablicy lub mówisz o ostatnim indeksie, to dokładnie to, co chcesz. – hobbs

+0

Właśnie zdałem sobie sprawę, że bardzo ładnie wspomniałeś "_efektywny sposób". Czy chcesz komentarze na temat wydajności, kodu i/lub odpowiedzi? – zdim

Odpowiedz

1

Przygotuj skrót, aby skutecznie zidentyfikować indeksy, a następnie zindeksuj do oryginalnej tablicy.

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

@arr_filt końcowe zawiera elementy @arr_orig indices innych niż te, w @ind_toss.

Zobacz rozwiązanie według ysth w this post do filtrowania elementów tablic przez inną tablicę.


Zawiń w podpaskę i uruchom. Tablica z indeksami do wykluczenia to @ind_toss, oryginalna tablica to @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)] ]; 
} 

Drukuje

a b c d e 

Uwagi

return z sub, jak wspomniał w komentarzu przez Oleg V. Volkov, można również zapisać jako

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

Dzięki temu unika się budowania listy przez grep i plasterek, ale raczej indeksuje się do tablicy warunkowo.

+0

Właściwie to drukuje '6' – ChatterOne

+0

@ChatterOne Naprawiono, dziękuję bardzo. Literówka z innej wersji :( – zdim

+0

Dlaczego 'grep' + slice, jeśli możesz" mapować "od razu i pozbyć się tablic indeksów tymczasowych? –

2

Nie potrzebujesz niczego poza array slice, więc uniknęłbym tworzenia subwagi tylko po to.

my @wanted = @array[@indices]; 

Jeśli pracujesz z odniesieniami tablicy, ten sam przepis ma zastosowanie:

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

Uważam, że OP musi _wyłączyć_ elementy na tych indeksach. – zdim

0

Wystarczy oczyścić trochę na odpowiedź zdim (która jest poprawna w każdym razie):

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