2013-01-09 10 views
6

Jeśli chcę, aby wyodrębnić tylko 4, 5, i elementy 7 (powiedzmy) rekord zakładce rozdzielone, mogę zrobić coś takiego:Jak określić "plasterek ogona" w Perlu?

my @f = (split(/\t/, $_, -1))[3, 4, 6]; 

ale co jeśli chcę 4th elementu i „ogon plasterek "składający się ze wszystkich elementów od siódmej do końca tablicy? Nie wiem, jak to zrobić w jednej linii. Najlepsze, co mogę zrobić, to w ten sposób:

my @f = split(/\t/, $_, -1); 
@f = @f[3, 6..$#f]; 

Jedynym powodem, dla wykonywania tej operacji w dwóch liniach jest tak, że można określić $#f w drugiej linii, ale to wiąże się z większą swoistością niż jest nieodłączną częścią zadanie; zadanie tak naprawdę nie ma wartości care ile elementów ma wartość zwróconą przez split. Byłoby miło móc określić coś w stylu "wszystko, co jest dostępne od siódmego elementu". To właśnie mam na myśli przez "plasterek ogona": plasterek, w którym określony jest tylko punkt początkowy, a punkt końcowy jest pozostawione niejawne.

(Ten rodzaj specyfikacji jest powszechne w zastosowaniach narzędzia cut w Uniksie, np:

... | cut -f 4,7- 

)

Czy jest jakiś wyraz indeksowanie, że mogę zwrócić się bezpośrednio do (split(...)) podwyrażenie aby wytworzyć w jednym wierszu ten sam efekt, jaki osiągają dwie ostatnie linie kodu powyżej?

EDYCJA: Aby było jasne, próbuję uniknąć konstrukcji $#ARRAY. Wiem, że zawsze mogę coś zrobić jak

my @f = do { my @t = split(/\t/, $_, -1); @t[3, 6..$#t] }; 

Odpowiedz

8

wyrażenia w nawiasach plasterka lista musi zwrócić listę zero lub więcej indeksów. Musisz więc wiedzieć, ile przedmiotów na liście jest krojonych, zanim zostaną wyprodukowane. Więc nie, nie można tego zrobić za pomocą wycinka listy.

Najbardziej bezpośredni sposób uzyskiwania dostępu do listy na stosie odbywa się przez @_. To wymaga połączenia dodatkowego, ale daje łatwy mechanizm opuszczania listy na stosie.

my @f = sub { @_[6..$#_] }->(split(/\t/, $_, -1)); 

Zauważ, że to rozwiązanie nie tworzy tablicę i skopiować wartości w tej tablicy jak w kodzie już od dodanego do Twojego pytania.

+0

Rozszerzyłem moją odpowiedź. – ikegami

+0

bardzo fajna myśl –

+1

Niiiiice. Podoba mi się użycie '@ _', aby uniknąć tam tymczasowych kopii. – LeoNerd