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?
Odpowiedz
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.
Właściwie to drukuje '6' – ChatterOne
@ChatterOne Naprawiono, dziękuję bardzo. Literówka z innej wersji :( – zdim
Dlaczego 'grep' + slice, jeśli możesz" mapować "od razu i pozbyć się tablic indeksów tymczasowych? –
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];
Uważam, że OP musi _wyłączyć_ elementy na tych indeksach. – zdim
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];
}
Bardziej na marginesie: '0 .. (skalar (@ {$ x}) - 1)' jest znacznie łatwiejsze do zapisania '0 .. $ # $ x' lub jeśli wolisz' 0 .. $ # {$ x} '. – hobbs
'$ # 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
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