Jest to polecenie perllol, które można uruchomić w darmowym dostawcy usług hostingowych OnWorks przy użyciu jednej z naszych wielu bezpłatnych stacji roboczych online, takich jak Ubuntu Online, Fedora Online, emulator online systemu Windows lub emulator online MAC OS
PROGRAM:
IMIĘ
perllol — Manipulowanie tablicami w Perlu
OPIS
Deklaracja oraz Uzyskiwania dostępu of Tablice of Tablice
Najprostszą dwupoziomową strukturą danych do zbudowania w Perlu jest czasami tablica tablic
niedbale nazywana listą list. Jest to dość łatwe do zrozumienia i prawie
wszystko, co ma zastosowanie tutaj, będzie miało również zastosowanie później w przypadku bardziej zaawansowanych danych
Struktury.
Tablica tablicy to po prostu zwykła stara tablica @AoA, którą można uzyskać za pomocą dwóch
indeksy dolne, takie jak $AoA[3][2]. Oto deklaracja tablicy:
użyj 5.010; #, więc możemy użyć say()
# przypisz do naszej tablicy tablicę odwołań do tablicy
@AoA = (
[ „fred”, „barney”, „kamyki”, „bambam”, „dino”, ],
[ „george”, „jane”, „elroy”, „judy”, ],
["homer", "bart", "marge", "maggie", ],
);
powiedz $AoA[2][1];
bart
Teraz należy bardzo uważać, aby nawias zewnętrzny był okrągły, czyli a
nawias. Dzieje się tak dlatego, że przypisujesz do tablicy @, więc potrzebujesz nawiasów. Jeśli
chciałeś tam nie być @AoA, ale raczej tylko odniesieniem do niego, możesz to zrobić
coś więcej takiego:
# przypisz odwołanie do tablicy odwołań do tablicy
$ref_to_AoA = [
[ „fred”, „barney”, „kamyki”, „bambam”, „dino”, ],
[ „george”, „jane”, „elroy”, „judy”, ],
["homer", "bart", "marge", "maggie", ],
];
powiedz $ref_to_AoA->[2][1];
bart
Zauważ, że zmienił się typ nawiasu zewnętrznego, a co za tym idzie, zmieniła się także nasza składnia dostępu.
Dzieje się tak dlatego, że w przeciwieństwie do C, w Perlu nie można swobodnie wymieniać tablic i referencji
do tego. $ref_to_AoA jest referencją do tablicy, natomiast @AoA jest właściwą tablicą.
Podobnie $AoA[2] nie jest tablicą, ale odnośnikiem do tablicy. Więc jak to możliwe, że możesz napisać te:
$AoA[2] [2]
$ref_to_AoA->[2][2]
zamiast pisać te:
$AoA[2]->[2]
$ref_to_AoA->[2]->[2]
Cóż, dzieje się tak, ponieważ reguła jest taka, że tylko w sąsiednich nawiasach (kwadratowych lub kręconych)
możesz pominąć strzałkę dereferencji wskaźnika. Ale nie możesz tego zrobić dla samego
pierwszy, jeśli jest to skalar zawierający referencję, co oznacza, że $ref_to_AoA zawsze
potrzebuje tego.
Rozwój Twoje Własny
To wszystko dobrze i dobrze, jeśli chodzi o deklarację stałej struktury danych, ale co, jeśli chcesz
dodawać nowe elementy na bieżąco, czy też budować je całkowicie od zera?
Najpierw przyjrzyjmy się wczytaniu go z pliku. Przypomina to dodanie wiersza w punkcie a
czas. Załóżmy, że istnieje plik płaski, w którym każda linia jest wierszem, a każde słowo an
element. Jeśli próbujesz opracować tablicę @AoA zawierającą te wszystkie elementy, oto prawo
sposób na to:
podczas (<>) {
@tmp = podział;
wciśnij @AoA, [ @tmp ];
}
Mogłeś również załadować to z funkcji:
dla $i ( 1 .. 10 ) {
$AoA[$i] = [jakaśfunkcja($i) ];
}
Lub mogłeś mieć zmienną tymczasową z zawartą w niej tablicą.
dla $i ( 1 .. 10 ) {
@tmp = jakaś funkcja($i);
$AoA[$i] = [ @tmp];
}
Ważne jest, aby upewnić się, że używasz konstruktora odniesienia do tablicy „[ ]”. To jest ponieważ
to by nie zadziałało:
$AoA[$i] = @tmp; # ZŁO!
Powodem, dla którego nie robi się tego, co chcesz, jest przypisanie takiej nazwanej tablicy do a
skalar przyjmuje tablicę w kontekście skalarnym, co oznacza, że po prostu liczy liczbę
elementy w @tmp.
Jeśli działasz w trybie „użyj ściśle” (a jeśli nie, to dlaczego, u licha, nie jesteś?),
będziesz musiał dodać kilka deklaracji, aby było miło:
używaj ścisłego;
moje(@AoA, @tmp);
podczas (<>) {
@tmp = podział;
wciśnij @AoA, [ @tmp ];
}
Oczywiście nie potrzebujesz tablicy tymczasowej, aby w ogóle mieć nazwę:
podczas (<>) {
wciśnij @AoA, [podziel];
}
Nie musisz też używać Pchać(). Mógłbyś po prostu przypisać bezpośrednie zadanie, gdybyś wiedział
gdzie chciałeś to umieścić:
mój (@AoA, $i, $line);
dla $i ( 0 .. 10 ) {
$linia = <>;
$AoA[$i] = [podział " ",$linia];
}
a nawet po prostu
mój (@AoA, $i);
dla $i ( 0 .. 10 ) {
$AoA[$i] = [ podziel " ", <> ];
}
Ogólnie rzecz biorąc, powinieneś zachować ostrożność w przypadku korzystania z funkcji, które mogą potencjalnie zwracać listy
kontekst skalarny bez wyraźnego określenia tego. Byłoby to bardziej zrozumiałe dla zwykłego człowieka
czytelnik:
mój (@AoA, $i);
dla $i ( 0 .. 10 ) {
$AoA[$i] = [ podział " ", skalar(<>) ];
}
Jeśli chcesz mieć zmienną $ref_to_AoA jako odniesienie do tablicy, musisz to zrobić
coś takiego:
podczas (<>) {
push @$ref_to_AoA, [podział];
}
Teraz możesz dodawać nowe wiersze. A co z dodaniem nowych kolumn? Jeśli masz do czynienia z po prostu
macierzy, często najłatwiej jest zastosować proste przypisanie:
za $x (1 .. 10) {
za $y (1 .. 10) {
$AoA[$x][$y] = func($x, $y);
}
}
za x $ ( 3, 7, 9 ) {
$AoA[$x][20] += func2($x);
}
Nie ma znaczenia, czy te elementy już są, czy nie: chętnie stworzy
je za ciebie, ustawiając interweniujące elementy na „undef”, jeśli zajdzie taka potrzeba.
Jeśli chcesz po prostu dołączyć do wiersza, musisz zrobić coś zabawniejszego:
# dodaj nowe kolumny do istniejącego wiersza
push @{ $AoA[0] }, "wilma", "betty"; # wyraźny deref
Przed Perlem 5.14 nie można było tego nawet skompilować:
wciśnij $AoA[0], "wilma", "betty"; # niejawna deref
Dlaczego? Bo kiedyś argument za Pchać() musiała być prawdziwą tablicą, nie
tylko odniesienie do jednego. To już nie jest prawdą. W rzeczywistości linia oznaczona jako „ukryte deref”
powyżej działa dobrze - w tym przypadku - robiąc to samo, co zrobił ten, który mówi o jawnym deref.
Powodem, dla którego powiedziałem „w tym przypadku”, jest to, że tylko działa, ponieważ $AoA[0] już
posiadał odwołanie do tablicy. Jeśli spróbujesz tego na niezdefiniowanej zmiennej, weźmiesz
wyjątek. To dlatego, że niejawne wyłuskanie nigdy nie spowoduje automatycznego ożywienia niezdefiniowanego
zmienną w sposób, w jaki „@{ }” zawsze będzie:
mój $aref = undef;
push $aref, qw (więcej wartości); # ZŁO!
push @$aref, qw(jeszcze kilka); # OK
Jeśli chcesz skorzystać z tego nowego, ukrytego zachowania polegającego na wyłuskiwaniu referencji, śmiało:
sprawia, że kod jest mniej męczący dla oka i nadgarstka. Po prostu zrozum, że starsze wersje będą się dławić
na nim podczas kompilacji. Zawsze, gdy używasz czegoś, co działa tylko w niektórych przypadkach
danego wydania Perla i późniejszych, ale nie wcześniejszych, należy umieścić widoczne
użyj wersji 5.14; # potrzebne do niejawnego usuwania odwołań do tablicy przez operacje na tablicy
dyrektywę na górze pliku, który jej potrzebuje. W ten sposób, gdy ktoś próbuje uruchomić plik
nowy kod pod starym Perlem, zamiast otrzymywać błąd podobny do
Typ arg 1 do wypchnięcia musi być tablicą (nie elementem tablicy) w /tmp/a wiersz 8, w pobliżu ""betty";"
Wykonywanie /tmp/a zostało przerwane z powodu błędów kompilacji.
zostaną o tym grzecznie poinformowani
Wymagany jest Perl w wersji 5.14.0 — to tylko wersja 5.12.3, zatrzymana w wierszu 1 /tmp/a.
BEGIN nie powiodło się — kompilacja została przerwana w /tmp/a w wierszu 1.
Uzyskiwania dostępu oraz Drukowanie
Teraz nadszedł czas, aby wydrukować strukturę danych. Jak masz zamiar to zrobić? Więc jeśli
chcesz tylko jeden z elementów, to trywialne:
drukuj $AoA[0][0];
Jeśli jednak chcesz wydrukować całość, nie możesz tego powiedzieć
drukuj @AoA; # ZŁO
ponieważ otrzymasz listę tylko referencji, a Perl nigdy nie będzie automatycznie usuwał referencji
rzeczy dla ciebie. Zamiast tego musisz rzucić sobie pętlę lub dwie. To drukuje całość
struktura, używając stylu powłoki Do() skonstruować pętlę przez zewnętrzny zestaw
indeksy dolne.
dla $aref ( @AoA ) {
powiedz „\t [ @$aref ],”;
}
Jeśli chcesz śledzić indeksy dolne, możesz to zrobić:
dla $i ( 0 .. $#AoA ) {
powiedz "\t elt $i to [ @{$AoA[$i]} ],";
}
a może nawet to. Zwróć uwagę na wewnętrzną pętlę.
dla $i ( 0 .. $#AoA ) {
dla $j ( 0 .. $#{$AoA[$i]} ) {
powiedz "elt $i $j to $AoA[$i][$j]";
}
}
Jak widać, robi się to trochę skomplikowane. Dlatego czasami łatwiej jest wziąć
tymczasowe w drodze przez:
dla $i ( 0 .. $#AoA ) {
$aref = $AoA[$i];
dla $j ( 0 .. $#{$aref} ) {
powiedz "elt $i $j to $AoA[$i][$j]";
}
}
Hmm... to nadal trochę brzydkie. Co powiesz na to:
dla $i ( 0 .. $#AoA ) {
$aref = $AoA[$i];
$n = @$aref - 1;
dla $j ( 0 .. $n ) {
powiedz "elt $i $j to $AoA[$i][$j]";
}
}
Kiedy znudzi Ci się pisanie niestandardowego wydruku dla struktur danych, możesz zajrzeć do
standardowe moduły Dumpvalue lub Data::Dumper. Pierwszą z nich jest debugger Perla
używa, podczas gdy ten drugi generuje parsowalny kod Perla. Na przykład:
użyj wersji 5.14; # używając prototypu +, nowość w wersji 5.14
podprogram(+) {
wymagają wartości zrzutu;
stan $ładnie = nowa wartość zrzutu::
zaznacz => q("),
compactDump => 1, # skomentuj te dwie linie
veryCompact => 1, # jeśli chcesz mieć większy zrzut
;
dumpValue $ładnie @_;
}
# Przypisz listę odwołań do tablicy do tablicy.
mój @AoA = (
[ „fred”, „barney” ],
["george", "jane", "elroy"],
[ „homer”, „marge”, „bart” ],
);
wciśnij $AoA[0], "wilma", "betty";
pokaż @AoA;
wydrukuje:
0 0..3 "fred" "barney" "wilma" "betty"
1 0..2 "george" "jane" "elroy"
2 0..2 „homer” „marża” „bart”
Natomiast jeśli skomentujesz dwie linijki, o których powiedziałem, że możesz chcieć, to ci to pokaże
zamiast tego w ten sposób:
0 SZYK(0x8031d0)
0 „fred”
1 „barney”
2 "wilma"
3 „Betty”
1 SZYK(0x803d40)
0 "George"
1 „Jana”
2 „elroy”
2 SZYK(0x803e10)
0 "dom"
1 „marża”
2 „barty”
Plasterki
Jeśli chcesz dostać się do wycinka (części wiersza) w tablicy wielowymiarowej, masz zamiar
muszę zrobić jakąś fantazyjną subskrypcję. To dlatego, że chociaż mamy ładny synonim
pojedynczych elementów za pomocą strzałki wskaźnika w celu wyłuskiwania referencji, nie istnieje taka wygoda
plastry.
Oto jak wykonać jedną operację za pomocą pętli. Tak jak poprzednio, przyjmiemy zmienną @AoA.
@część = ();
x = 4 zł;
dla ($y = 7; $y < 13; $y++) {
wciśnij @część, $AoA[$x][$y];
}
Tę samą pętlę można zastąpić operacją plasterka:
@część = @{$AoA[4]}[7..12];
lub nieco odsunięte:
@część = @{ $AoA[4] } [ 7..12 ];
Ale jak możesz sobie wyobrazić, może to być dość trudne dla czytelnika.
Ach, ale co, jeśli chcesz dwuwymiarowy kawałek, na przykład $x biegnące od 4..8 i $y
biegać od 7 do 12? Hmm... oto prosty sposób:
@nowyAoA = ();
for ($startx = $x = 4; $x <= 8; $x++) {
for ($starty = $y = 7; $y <= 12; $y++) {
$newAoA[$x - $startx][$y - $starty] = $AoA[$x][$y];
}
}
Możemy zredukować niektóre zapętlenia przez plasterki
for ($x = 4; $x <= 8; $x++) {
push @noweAoA, [ @{ $AoA[$x] } [ 7..12 ] ];
}
Jeśli fascynowały Cię Transformacje Schwartza, prawdopodobnie wybrałbyś do tego mapę
@newAoA = mapa { [ @{ $AoA[$_] } [ 7..12 ] ] } 4 .. 8;
Chociaż jeśli Twój menedżer oskarży Cię o szukanie bezpieczeństwa pracy (lub szybkiej niepewności) poprzez
nieprzenikniony kod, trudno byłoby dyskutować. :-) Gdybym był tobą, umieściłbym to w
funkcjonować:
@newAoA = splice_2D( \@AoA, 4 => 8, 7 => 12 );
złącze pomocnicze_2D {
mój $lrr = przesunięcie; # odwołanie do tablicy odwołań do tablicy!
mój ($x_lo, $x_hi,
$y_lo, $y_hi) = @_;
zwróć mapę {
[ @{ $lrr->[$_] } [ $y_lo .. $y_hi ] ]
} $x_lo .. $x_hi;
}
Korzystaj z Perllol online, korzystając z usług onworks.net