Tablice indeksowane przechowują serie jednej lub więcej wartości uporządkowane ta, że do każdej z wartości można uzyskać dostęp za pomocą nieoznakowanej wartości całkowitej. Pierwszy indeks to zawsze liczba 0, a jego przyrost dla każdego kolejnego dodanego do tablicy elementu to 1. W języku ActionScript 3.0 dwie klasy są używane jako tablice indeksowane: klasa Array i klasa Vector.
W tablicach indeksowanych liczba indeksu jest nieoznakowaną 32-bitową liczbą całkowitą. Maksymalny rozmiar tablicy indeksowanej to 2
32
- 1 lub 4 294 967 295. Próba utworzenia tablicy wykraczającej poza rozmiar maksymalny skutkuje błędem wykonania.
Aby uzyskać dostęp do określonego elementu tablicy indeksowanej, należy skorzystać z operatora dostępu do tablicy (
[]
) w celu określenia indeksu elementu, do którego jest uzyskiwany dostęp. Poniższy kod reprezentuje na przykład pierwszy element (element z indeksem 0) w tablicy indeksowanej o nazwie
songTitles
.
songTitles[0]
Połączenie nazwy zmiennej tablicy z indeksem w nawiasach kwadratowych pełni rolę pojedynczego identyfikatora. (Innymi słowy: może być używana w dowolny sposób, w jaki można korzystać z nazwy zmiennej). Do elementu tablicy indeksowanej można przypisać wartość, korzystając z nazwy i indeksu po lewej stronie instrukcji przypisania:
songTitles[1] = "Symphony No. 5 in D minor";
I podobnie: z elementu tablicy indeksowanej można uzyskać wartość, korzystając z nazwy i indeksu po prawej stronie instrukcji przypisania:
var nextSong:String = songTitles[2];
Można również użyć zmiennej w nawiasach kwadratowych zamiast jawnego określania wartości. (Zmienna musi zawierać nieujemną liczbę całkowitą, taką jak unit, dodatnia wartość int lub dodatnia instancja Number (integer)). Ta technika jest używana najczęściej w celu wykonania pętli po elementach w tablicy indeksowanej oraz w celu wykonania operacji na niektórych lub wszystkich tych elementach. Poniższy kod demonstruje tę technikę. W kodzie zastosowano pętlę w celu uzyskania dostępu do każdej wartości w obiekcie Array o nazwie
oddNumbers
. Instrukcja
trace()
służy do wyświetlania każdej wartości w postaci „oddNumber[
indeks
] =
wartość
”.
var oddNumbers:Array = [1, 3, 5, 7, 9, 11];
var len:uint = oddNumbers.length;
for (var i:uint = 0; i < len; i++)
{
trace("oddNumbers[" + i.toString() + "] = " + oddNumbers[i].toString());
}
Klasa Array
Pierwszy typ tablicy indeksowanej to klasa Array. Instancja klasy Array może zawierać wartość danych dowolnego typu. Jeden obiekt Array może zawierać obiekty różnych typów danych. Na przykład: pojedyncza instancja klasy Array może zawierać wartość String w indeksie 0, instancję Number w indeksie 1 i obiekt XML w indeksie 2.
Klasa Vector
Innym typem tablicy indeksowanej, który jest dostępny w języku ActionScript 3.0, jest klasa Vector. Wystąpienie klasy Vector jest
tablicą określonego typu
, co oznacza, że wszystkie elementy w wystąpieniu klasy Vector mają zawsze ten sam typ danych.
Uwaga:
Klasa Vector jest dostępna począwszy od wersji 10 programu Flash Player 10 i wersji 1.5 środowiska Adobe AIR.
Podczas deklarowania zmiennej Vector lub tworzenia instancji obiektu Vector należy jawnie określić typ danych obiektów, jakie może zawierać instancja klasy Vector. Podany w tym miejscu typ danych jest określany jako
typ bazowy
klasy Vector. W czasie wykonywania oraz w czasie kompilacji (w trybie dokładnym) sprawdzany jest każdy kod, który ustawia wartość elementu Vector lub pobiera wartość z elementu Vector. Jeśli typ danych obiektu dodawanego lub pobieranego nie jest zgodny z typem bazowym Vector, powstaje błąd.
Oprócz ograniczeń dotyczących typów danych klasa Vector posiada inne, które odróżniają ją od klasy Array:
-
Instancja Vector to tablica zagęszczona. Obiekt Array może zawierać wartości w indeksach 0 i 7, nawet jeśli nie zawiera wartości w pozycjach od 1 do 6. Jednak wystąpienie klasy Vector musi zawierać wartość (lub element
null
) pod każdym indeksem.
-
Instancja klasy Vector może opcjonalnie mieć stałą długość. Oznacza to, że liczba elementów, jakie zawiera ta instancja Vector, nie może ulec zmianie.
-
Dostęp do elementów instancji klasy Vector jest sprawdzany pod względem ograniczeń zakresu. Niemożliwy jest odczyt wartości w pozycji indeksu większego od ostatniego elementu (
length
- 1). Nie można ustawić wartości w indeksie przekraczającym bieżący ostatni indeks o jeden. (Czyli można ustawić wartość jedynie w pozycji istniejącego indeksu lub indeksu
[length]
).
W wyniku tych ograniczeń wystąpienie klasy Vector charakteryzują trzy podstawowe zalety, których nie ma wystąpienie klasy Array z elementami należącymi do jednej klasy:
-
Wydajność: w porównaniu z instancją Array dostęp i iteracje elementów tablicy można uzyskać dużo szybciej w przypadku instancji Vector.
-
Bezpieczeństwo typu: w trybie dokładnym kompilator może wskazywać błędy dotyczące typu danych. Do przykładów takich błędów należą: przypisywanie wartości niepoprawnego typu danych do instancji klasy Vector lub oczekiwanie niepoprawnego typu danych podczas odczytu wartości z instancji klasy Vector. W czasie wykonywania typy danych również są sprawdzane podczas dodawania danych lub odczytywania danych z obiektu Vector. Użycie metody
push()
lub
unshift()
w celu dodania wartości do wystąpienia klasy Vector powoduje, że typy danych argumentów nie są sprawdzane w czasie kompilacji. Podczas korzystania z tych metod wartości są sprawdzane w czasie wykonywania.
-
Niezawodność: Sprawdzanie zakresów w czasie wykonywania (lub sprawdzanie stałych długości) powoduje, że niezawodność operowania na obiektach klasy Vector jest znacznie większa niż w przypadku operowania na obiektach klasy Array.
Oprócz dodatkowych ograniczeń i zalet klasa Vector bardzo przypomina klasę Array. Właściwości i metody obiektu Vector są podobne — w większości identyczne — do właściwości i metod obiektu Array. W większości przypadków, w których można zastosować klasę Array, w której wszystkie elementy należą do tego samego typu danych, preferowane jest zastosowanie instancji Vector.
Tworzenie tablic
Istnieje kilka technik tworzenia instancji klasy Array lub klasy Vector. Jednak techniki służące do tworzenia poszczególnych typów tablic są różne.
Tworzenie instancji klasy Array
Obiekt Array można utworzyć przez wywołanie konstruktora
Array()
lub za pomocą składni literału Array.
Funkcja konstruktora
Array()
może być używana na trzy sposoby. Po pierwsze, wywołanie konstruktora bez argumentów daje tablicę pustą. Użytkownik może skorzystać z właściwości
length
klasy Array w celu upewnienia się, że tablica nie zawiera żadnych elementów. Na przykład w poniższym kodzie wywoływany jest konstruktor
Array()
bez argumentów.
var names:Array = new Array();
trace(names.length); // output: 0
Po drugie, używanie liczby w charakterze jedynego parametru dla konstruktora
Array()
powoduje, że tworzona jest tablica o tej długości, a wartość każdego z jej elementów jest ustawiona na
undefined
. Argument musi być nieoznaczoną liczbą całkowitą z przedziału od 0 do 4 294 967 295. Na przykład w poniższym kodzie wywoływany jest konstruktor
Array()
z pojedynczym argumentem liczbowym.
var names:Array = new Array(3);
trace(names.length); // output: 3
trace(names[0]); // output: undefined
trace(names[1]); // output: undefined
trace(names[2]); // output: undefined
Po trzecie, wywołanie konstruktora i przekazanie listy elementów jako parametrów powoduje utworzenie tablicy z elementami odpowiadającymi poszczególnym parametrom. Poniższy kod powoduje przekazanie trzech argumentów do konstruktora
Array()
.
var names:Array = new Array("John", "Jane", "David");
trace(names.length); // output: 3
trace(names[0]); // output: John
trace(names[1]); // output: Jane
trace(names[2]); // output: David
Tablice można również tworzyć za pomocą literałów Array. Literał Array może zostać przypisany bezpośrednio do zmiennej tablicy, zgodnie z przykładem poniżej:
var names:Array = ["John", "Jane", "David"];
Tworzenie instancji klasy Vector
W celu utworzenia wystąpienia klasy Vector należy wywołać konstruktor
Vector.<T>()
. Wystąpienie klasy Vector można również utworzyć przez wywołanie funkcji globalnej
Vector.<T>()
. Ta funkcja konwertuje określony obiekt na wystąpienie klasy Vector. W programie Flash Professional CS5 i nowszych wersjach, Flash Builder 4 i nowszych wersjach oraz Flex 4 i nowszych wersjach można także utworzyć instancję wektora, korzystając ze składni literału klasy Vector.
Przy każdej deklaracji zmiennej Vector (podobnie jak parametru Vector albo typu wartości zwracanej przez metodę) określany jest typ bazowy zmiennej Vector. Typ bazowy jest również określany podczas tworzenia wystąpienia klasy Vector przez wywołanie konstruktora
Vector.<T>()
. Oznacza to, że każdemu wpisowi
Vector
w języku ActionScript towarzyszy typ bazowy.
Do utworzenia typu bazowego Vector służy składnia parametru type. Parametr type występuje bezpośrednio za słowem
Vector
w kodzie. Składnia obejmuje znak kropki (
.
), a następnie nazwę klasy bazowej otoczoną nawiasami trójkątnymi (
<>
), tak jak w poniższym przykładzie.
var v:Vector.<String>;
v = new Vector.<String>();
W pierwszym wierszu przykładu zmienna
v
została zadeklarowana jako wystąpienie klasy
Vector.<String>
. Reprezentuje więc tablicę indeksowaną, która może zawierać tylko wystąpienia klasy String. W drugim wierszu jest wywoływany konstruktor
Vector()
w celu utworzenia wystąpienia o takim samym typie Vector (czyli obiektu Vector, w którym wszystkie elementy są obiektami String). Obiekt ten jest przypisywany do zmiennej
v
.
Korzystanie z funkcji Vector<T>()
Jeśli konstruktor
Vector.<T>()
jest używany bez żadnych argumentów, oznacza to, że tworzy on puste wystąpienie klasy Vector. W celu sprawdzenia, czy wystąpienie klasy Vector jest puste, należy sprawdzić wartość jego właściwość
length
. Poniższy przykładowy kod wywołuje konstruktor
Vector.<T>()
bez argumentów.
var names:Vector.<String> = new Vector.<String>();
trace(names.length); // output: 0
Jeśli z góry znana jest liczba elementów wymagana w wystąpieniu klasy Vector, można wstępnie zdefiniować liczbę elementów w wystąpieniu klasy Vector. W celu utworzenia wystąpienia klasy Vector z określoną liczbą elementów należy wprowadzić liczbę elementów jako pierwszy parametr (parametr
length
). Elementy wystąpienia klasy Vector nie mogą być puste, dlatego są wypełniane wystąpieniami typu bazowego. Jeśli typ bazowy jest typem odniesienia, który zezwala na wartości
null
, wówczas wszystkie elementy muszą zawierać wartość
null
. W przeciwnym wypadku wszystkie elementy będą zawierały wartość domyślną dla klasy. Na przykład zmienna uint nie może mieć wartości
null
. Z tego powodu w poniższym kodzie tworzone jest wystąpienie klasy Vector o nazwie
ages
z siedmioma elementami, a każdy z nich zawiera wartość 0.
var ages:Vector.<uint> = new Vector.<uint>(7);
trace(ages); // output: 0,0,0,0,0,0,0
Za pomocą konstruktora
Vector.<T>()
można również utworzyć obiekt Vector o stałej długości, wprowadzając wartość
true
dla drugiego parametru (parametru
fixed
). W takim przypadku instancja klasy Vector jest tworzona z określoną liczbą elementów, a liczby elementów nie można zmienić. Należy jednak pamiętać, że w instancji klasy Vector o stałej długości można zmieniać wartości elementów.
Korzystanie z konstruktora klasy Vector przy użyciu składni literału
W programie Flash Professional CS5 i nowszych wersjach, Flash Builder 4 i nowszych wersjach oraz Flex 4 i nowszych wersjach można przekazać listę wartości do konstruktora
Vector.<T>()
nie można przekazać listy wartości w celu określenia wartości początkowych wystąpienia klasy Vector.
// var v:Vector.<T> = new <T>[E0, ..., En-1 ,];
// For example:
var v:Vector.<int> = new <int>[0,1,2,];
Do tej składni odnoszą się następujące informacje:
-
Końcowy przecinek jest opcjonalny.
-
Puste elementy w tablicy nie są dozwolone; taka instrukcja, jak
var v:Vector.<int> = new <int>[0,,2,]
powoduje zgłoszenie błędu przez kompilator.
-
Nie można określić domyślnej długości instancji klasy Vector. Długość jest określana na podstawie liczby elementów na liście inicjującej instancję.
-
Nie można określić, czy instancja klasy Vector ma mieć stałą długość, czy nie. Należy zamiast tego skorzystać z właściwości
fixed
.
-
Jeśli elementy przekazane jako wartości nie będą zgodne z określonym typem, może dojść do utraty danych lub wystąpienia błędów. Na przykład:
var v:Vector.<int> = new <int>[4.2]; // compiler error when running in strict mode
trace(v[0]); //returns 4 when not running in strict mode
Korzystanie z funkcji globalnej Vector.<T>()
Oprócz konstruktora
Vector.<T>()
i składni literału klasy Vector można również użyć funkcji globalnej
Vector.<T>()
w celu utworzenia obiektu Vector. Funkcja globalna
Vector.<T>()
jest funkcją konwersji. Po wywołaniu funkcji globalnej
Vector.<T>()
należy określić typ bazowy wystąpienia klasy Vector, jaki będzie zwracany przez metodę. Jako argument należy wprowadzić pojedynczą tablicę indeksowaną (instancję klasy Array lub Vector). Następnie metoda zwróci instancję klasy Vector z określonym typem bazowym zawierającym wartości w argumencie tablicy źródłowej. Poniższy kod prezentuje składnię wywołania funkcji globalnej
Vector.<T>()
.
var friends:Vector.<String> = Vector.<String>(["Bob", "Larry", "Sarah"]);
Funkcja globalna
Vector.<T>()
wykonuje konwersje typów danych na dwóch poziomach. Najpierw: gdy instancja klasy Array zostanie przekazana do funkcji, wówczas następuje zwrócenie instancji klasy Vector. Następnie: niezależnie od tego, czy tablica źródłowa jest instancją klasy Array czy Vector, funkcja podejmuje próbę konwersji elementów tablicy źródłowej na wartości typu bazowego. Podczas konwersji wykorzystywane są standardowe reguły konwersji typu danych z języka ActionScript. Na przykład: poniższy kod konwertuje wartości String ze źródłowej instancji klasy Array na wartości całkowite w wynikowej instancji klasy Vector. Część dziesiętna pierwszej wartości (
"1.5"
) jest obcinana, a nieliczbowa trzecia wartość (
"Waffles"
) jest przekształcana na 0 w wyniku.
var numbers:Vector.<int> = Vector.<int>(["1.5", "17", "Waffles"]);
trace(numbers); // output: 1,17,0
Jeśli nie jest możliwa konwersja któregokolwiek z elementów źródłowych, występuje błąd.
Gdy kod wywoła funkcję globalną
Vector.<T>()
, a element w tablicy źródłowej jest wystąpieniem podklasy o określonym typie bazowym, wówczas element jest dodawany do wynikowego wystąpienia klasy Vector (nie występuje błąd). Użycie funkcji globalnej
Vector.<T>()
jest jedynym sposobem na konwersję wystąpienia klasy Vector o typie bazowym
T
na wystąpienie klasy Vector o typie bazowym będącym klasą nadrzędną klasy
T
.
Wstawianie elementów tablicy
Najprostszym sposobem dodania elementu do tablicy indeksowanej jest użycie operatora dostępu do tablicy (
[]
). Aby ustawić wartość elementu tablicy indeksowanej, należy użyć nazwy obiektu Array lub Vector oraz numeru indeksu po lewej stronie instrukcji przypisania:
songTitles[5] = "Happy Birthday";
Jeśli obiekt Array lub Vector nie zawiera jeszcze elementu w pozycji tego indeksu, indeks zostanie utworzony, a wartość zostanie w nim zapisana. Jeśli w pozycji tego indeksu istnieje wartość, nowa wartość zastąpi istniejącą.
Obiekt Array umożliwia utworzenie elementu w pozycji dowolnego indeksu. Jednak w przypadku obiektu Vector można tylko przypisać wartość do istniejącego indeksu lub do następnego dostępnego indeksu. Następny dostępny indeks odpowiada właściwości
length
obiektu Vector. Najbezpieczniejszym sposobem dodania nowego elementu do obiektu Vector jest użycie następującego fragmentu kodu:
myVector[myVector.length] = valueToAdd;
Trzy z metod klas Array i Vector —
push()
,
unshift()
i
splice()
— umożliwiają wstawianie elementów do tablicy indeksowanej. Metoda
push()
powoduje dołączenie co najmniej jednego elementu na końcu tablicy. Ostatni element wstawiony do tablicy za pomocą metody
push()
otrzymuje najwyższy numer indeksu. Metoda
unshift()
powoduje wstawienie co najmniej jednego elementu na początku tablicy — pod indeksem 0. Metoda
splice()
powoduje wstawienie dowolnej liczby pozycji pod określonym indeksem tablicy.
Poniższy przykład zawiera wszystkie trzy metody. Tworzona jest dowolna tablica o nazwie
planets
. Ma ona przechowywać nazwy planet w kolejności określonej ich odległością od Słońca. Przede wszystkim wywoływana jest więc metoda
push()
w celu dodania do tablicy pierwszego elementu:
Mars
. Następnie wywoływana jest metoda
unshift()
wstawiająca element przypadający na sam początek tablicy:
Mercury
. Na koniec wywoływana jest metoda
splice()
wstawiająca kolejno elementy
Venus
i
Earth
za pozycją
Mercury
, lecz przed pozycją
Mars
. Pierwszy argument wysłany do metody
splice()
, liczba całkowita 1, powoduje rozpoczęcie wstawiania od indeksu 1. Drugi argument wysyłany do metody
splice()
, liczba całkowita 0, wskazuje, że żadna z pozycji nie może zostać usunięta. Trzeci i czwarty argument wysyłane do metody
splice()
,
Venus
i
Earth
, to elementy, które mają zostać wstawione.
var planets:Array = new Array();
planets.push("Mars"); // array contents: Mars
planets.unshift("Mercury"); // array contents: Mercury,Mars
planets.splice(1, 0, "Venus", "Earth");
trace(planets); // array contents: Mercury,Venus,Earth,Mars
Metody
push()
i
unshift()
zwracają nieoznaczoną liczbę całkowitą reprezentującą długość zmodyfikowanej tablicy. Metoda
splice()
, użyta do wstawienia elementów, zwraca pustą tablicę co może wydawać się dziwne, jest jednak logiczne w kontekście uniwersalności działania metody
splice()
. Metody
splice()
można użyć nie tylko do wstawienia elementów do tablicy, lecz również do usunięcia z niej elementów. W przypadku korzystania z metody
splice()
do usuwania elementów zwraca ona tablicę zawierającą te usunięte elementy.
Uwaga:
Jeśli właściwość
fixed
obiektu Vector ma wartość
true
, wówczas liczba elementów w obiekcie Vector nie może ulec zmianie. W przypadku próby dodania nowego elementu do obiektu Vector o stałej długości za pomocą technik opisanych w tej sekcji dochodzi do powstania błędu.
Pobieranie wartości i usuwanie elementów tablic
Najprostszym sposobem na pobranie wartości elementu z tablicy indeksowanej jest użycie operatora dostępu do tablicy (
[]
). Aby pobrać wartość elementu tablicy indeksowanej, należy użyć nazwy obiektu Array lub Vector oraz numeru indeksu po prawej stronie instrukcji przypisania:
var myFavoriteSong:String = songTitles[3];
Możliwa jest próba pobrania wartości z obiektu Array lub Vector przy użyciu indeksu, który nie zawiera żadnego elementu. W takim przypadku obiekt Array zwróci wartość undefined, a obiekt Vector zgłosi wyjątek RangeError.
Trzy metody klas Array i Vector —
pop()
,
shift()
i
splice()
— umożliwiają usuwanie elementów. Metoda
pop()
umożliwia usunięcie elementu z końca tablicy. Innymi słowy, usuwa ona element o najwyższym indeksie. Metoda
shift()
usuwa element z początku tablicy, co oznacza, że zawsze usuwa element o indeksie równym 0. Metoda
splice()
, która może być również używana do wstawiana elementów, usuwa podaną liczbę elementów, rozpoczynając od indeksu o numerze podanym w pierwszym argumencie wysłanym do metody.
W poniższym przykładzie użyto wszystkich trzech metod w celu usunięcia elementów z wystąpienia klasy Array. Utworzona została tablica o nazwie
oceans
, która ma zawierać nazwy dużych zbiorników wodnych. Niektóre z nazw w tablicy to raczej jeziora niż oceany, dlatego potrzebne jest ich usunięcie.
Najpierw metoda
splice()
jest używana do usunięcia pozycji
Aral
i
Superior
oraz wstawiania pozycji
Atlantic
i
Indian
. Pierwszy argument wysyłany do metody
splice()
, liczba całkowita 2, wskazuje, że operacja powinna zostać rozpoczęta od trzeciej pozycji na liście — indeksu o numerze 2. Drugi argument — 2 — oznacza, że należy usunąć dwa elementy. Pozostałe argumenty,
Atlantic
i
Indian
, są wartościami, które należy wstawić pod indeksem 2.
Następnie metoda
pop()
usuwa ostatni element tablicy,
Huron
. W kolejnym kroku metoda
shift()
usuwa pierwszy element tablicy,
Victoria
.
var oceans:Array = ["Victoria", "Pacific", "Aral", "Superior", "Indian", "Huron"];
oceans.splice(2, 2, "Arctic", "Atlantic"); // replaces Aral and Superior
oceans.pop(); // removes Huron
oceans.shift(); // removes Victoria
trace(oceans);// output: Pacific,Arctic,Atlantic,Indian
Metody
pop()
i
shift()
zwracają usunięte elementy. W przypadku instancji klasy typ danych wartości zwracanej to Object, ponieważ tablice mogą zawierać dane dowolnego typu. W przypadku instancji klasy Vector typ danych wartości zwracanej jest typem bazowym klasy Vector. Metoda
splice()
zwraca obiekt Array lub Vector zawierający usunięte wartości. Przykład oparty na tablicy
oceans
można zmienić w taki sposób, aby wywołanie metody
splice()
powodowało przypisanie zwróconej tablicy do nowej zmiennej tablicy, zgodnie z poniższym przykładem.
var lakes:Array = oceans.splice(2, 2, "Arctic", "Atlantic");
trace(lakes); // output: Aral,Superior
Użytkownik może również spotkać się z kodem, który korzysta z operatora
delete
dla elementu obiektu Array. Operator
delete
ustawia dla elementu obiektu Array wartość
undefined
, lecz nie usuwa elementu z tablicy. Na przykład poniższy kod korzysta z operatora
delete
dla trzeciego elementu w tablicy
oceans
, lecz długość tablicy pozostaje równa 5.
var oceans:Array = ["Arctic", "Pacific", "Victoria", "Indian", "Atlantic"];
delete oceans[2];
trace(oceans);// output: Arctic,Pacific,,Indian,Atlantic
trace(oceans[2]); // output: undefined
trace(oceans.length); // output: 5
Obiekt Array lub Vector można skrócić za pomocą właściwości
length
. Po ustawieniu właściwości
length
tablicy indeksowanej na wartość mniejszą od aktualnej długości tablicy jest ona skracana, co powoduje usunięcie elementów zapisanych pod numerem indeksu wyższym niż nowa wartość właściwości
length
pomniejszona o 1. Jeśli na przykład tablica
oceans
została posortowana tak, że wszystkie poprawne elementy znajdują się w jej górnej części, można za pomocą właściwości
length
usunąć elementy z końca tablicy, zgodnie z poniższym kodem.
var oceans:Array = ["Arctic", "Pacific", "Victoria", "Aral", "Superior"];
oceans.length = 2;
trace(oceans); // output: Arctic,Pacific
Uwaga:
Jeśli właściwość
fixed
obiektu Vector ma wartość
true
, wówczas liczba elementów w obiekcie Vector nie może ulec zmianie. W przypadku próby usunięcia elementu lub skrócenia obiektu Vector o stałej długości za pomocą technik opisanych w tej sekcji dochodzi do powstania błędu.
Sortowanie tablicy
Dostępne są trzy metody —
reverse()
,
sort()
oraz
sortOn()
— umożliwiające zmienianie kolejności elementów tablicy indeksowanej przez sortowanie albo odwracanie kolejności. Wszystkie te metody modyfikują istniejącą tablicę. W poniższej tabeli przedstawiono podsumowanie tych metod oraz ich zachowanie dla obiektów Array i Vector:
Metoda
|
Zachowanie obiektu Array
|
Zachowanie obiektu Vector
|
reverse()
|
Zmienia kolejność elementów w taki sposób, że ostatni element staje się pierwszym elementem, a element przedostatni staje się drugim itd.
|
Takie same, jak zachowanie obiektu Array
|
sort()
|
Umożliwia sortowanie elementów obiektu Array na różne (predefiniowane) sposoby, np. w porządku alfabetycznym i liczbowym. Można również określić niestandardowy algorytm sortowania.
|
Sortuje elementy zgodnie ze zdefiniowanym niestandardowym algorytmem sortowania
|
sortOn()
|
Umożliwia sortowanie obiektów, które zawierają jedną lub większą liczbę wspólnych właściwości — poprzez określenie jednej lub większej liczby właściwości, jakie zostaną wykorzystane jako klucze sortowania
|
Niedostępne w klasie Vector
|
Metoda reverse()
Metoda
reverse()
nie korzysta z żadnych parametrów i nie zwraca wartości; pozwala ona jednak odwracać kolejność w tablicy przez przełączanie między porządkiem aktualnym a „odwróconym”. Poniższy przykład ilustruje odwracanie kolejności listy oceanów w tablicy
oceans
.
var oceans:Array = ["Arctic", "Atlantic", "Indian", "Pacific"];
oceans.reverse();
trace(oceans); // output: Pacific,Indian,Atlantic,Arctic
Proste sortowanie za pomocą metody sort() (tylko klasa Array)
W przypadku wystąpienia klasy Array metoda
sort()
zmienia kolejność elementów, stosując
domyślny porządek sortowania
. Domyślny porządek sortowania ma następującą charakterystykę:
-
W sortowaniu jest rozróżniana wielkość znaków, co oznacza, że wielkie litery poprzedzają małe litery. Na przykład, litera D poprzedza literę b.
-
Sortowanie odbywa się rosnąco, co oznacza, że znaki o niższych kodach (jak A) poprzedzają znaki o wyższych kodach (jak B).
-
Sortowanie powoduje umieszczenie wartości identycznych w sąsiedztwie, lecz w losowej kolejności.
-
Sortowanie jest oparte na ciągach, co oznacza, że elementy są przed porównaniem konwertowane na ciągi. (Na przykład 10 poprzedza 3, ponieważ ciąg
"1"
ma niższy kod niż
"3"
).
Może okazać się, że konieczne jest posortowanie tablicy bez względu na wielkość liter lub w porządku malejącym. Może się również zdarzyć, że tablica będzie zawierała liczby, które będzie trzeba posortować w porządku liczbowym, nie zaś alfabetycznym. Metoda
sort()
klasy Array zawiera parametr
options
, umożliwiający zmianę poszczególnych opcji sortowania domyślnego. Opcje są definiowane zestawem stałych statycznych w klasie Array, zgodnie z poniższą listą:
-
Array.CASEINSENSITIVE
: Ta opcja powoduje nieroróżnianie wielkości liter przy sortowaniu. Na przykład mała litera b poprzedza wówczas wielką literę D.
-
Array.DESCENDING:
Ta opcja powoduje odwrócenie domyślnego, rosnącego porządku sortowania. Na przykład litera B poprzedza literę A.
-
Array.UNIQUESORT:
Ta opcja powoduje przerwanie sortowania w przypadku znalezienia dwóch identycznych wartości.
-
Array.NUMERIC:
Ta opcja powoduje sortowanie liczbowe (takie, w którym 3 poprzedza 10).
W poniższym przykładzie podkreślono niektóre z tych opcji. Tworzona jest tablica o nazwie
poets
, która jest następnie sortowana za pomocą kilku różnych opcji.
var poets:Array = ["Blake", "cummings", "Angelou", "Dante"];
poets.sort(); // default sort
trace(poets); // output: Angelou,Blake,Dante,cummings
poets.sort(Array.CASEINSENSITIVE);
trace(poets); // output: Angelou,Blake,cummings,Dante
poets.sort(Array.DESCENDING);
trace(poets); // output: cummings,Dante,Blake,Angelou
poets.sort(Array.DESCENDING | Array.CASEINSENSITIVE); // use two options
trace(poets); // output: Dante,cummings,Blake,Angelou
Niestandardowe sortowanie za pomocą metody sort() (klasy Array i Vector)
Oprócz sortowania podstawowego, jakie jest dostępne dla obiektu Array, można również zdefiniować niestandardową regułę sortowania. Ta technika jest jedyną formą metody
sort()
, jaka jest dostępna dla klasy Vector. Aby zdefiniować własne sortowanie, należy napisać własną funkcję sortowania i przekazać ją jako argument do metody
sort()
.
Załóżmy na przykład, że istnieje lista nazwisk, na której każdy element zawiera imię i nazwisko osoby, lecz lista powinna zostać posortowana według nazwisk. Należy użyć własnej funkcji w celu dokonania analizy każdego elementu i użycia do sortowania tylko części stanowiącej nazwisko. Poniższy kod ilustruje, jak można to zrobić za pomocą własnej funkcji użytej w charakterze parametru dla metody
Array.sort()
.
var names:Array = new Array("John Q. Smith", "Jane Doe", "Mike Jones");
function orderLastName(a, b):int
{
var lastName:RegExp = /\b\S+$/;
var name1 = a.match(lastName);
var name2 = b.match(lastName);
if (name1 < name2)
{
return -1;
}
else if (name1 > name2)
{
return 1;
}
else
{
return 0;
}
}
trace(names); // output: John Q. Smith,Jane Doe,Mike Jones
names.sort(orderLastName);
trace(names); // output: Jane Doe,Mike Jones,John Q. Smith
Własna funkcja sortująca
orderLastName()
korzysta z wyrażenia regularnego w celu wydzielenia nazwiska z każdego z elementów, co umożliwia ich porównanie w operacji porównania. Identyfikator funkcji
orderLastName
służy jako jedyny parametr wywołania metody
sort()
dla tablicy
names
. Funkcja sortowania przyjmuje dwa parametry —
a
oraz
b
— ponieważ działa ona na dwóch elementach tablicy jednocześnie. Zwracana wartość funkcji sortowania wskazuje, jak powinny być posortowane elementy.
-
Zwracana wartość wynosząca -1 wskazuje, że pierwszy z parametrów,
a
, poprzedza drugi z parametrów,
b
.
-
Zwracana wartość wynosząca 1 wskazuje, że drugi parametr,
b
, poprzedza pierwszy parametr,
a
.
-
Zwracana wartość wynosząca 0 wskazuje, że elementy mają jednakowe pierwszeństwo przy sortowaniu.
Metoda sortOn() (tylko klasa Array)
Metoda
sortOn()
jest przeznaczona dla obiektów Array zawierających elementy, które zawierają obiekty. Obiekty te powinny mieć co najmniej jedną wspólną właściwość, która może służyć jako klucz sortowania. Metoda
sortOn()
zastosowana dla tablic jakiegokolwiek innego typu zwraca wyniki inne niż oczekiwane.
Uwaga:
Klasa Vector nie zawiera metody
sortOn()
. Ta metoda jest dostępna tylko dla obiektów Array.
Poniższy przykład ilustruje modyfikację obiektu Array
poets
mającą na celu doprowadzenie do tego, by każdy jej element był obiektem, nie zaś ciągiem znaków. Każdy obiekt zawiera zarówno nazwisko poety, jak i rok jego urodzenia.
var poets:Array = new Array();
poets.push({name:"Angelou", born:"1928"});
poets.push({name:"Blake", born:"1757"});
poets.push({name:"cummings", born:"1894"});
poets.push({name:"Dante", born:"1265"});
poets.push({name:"Wang", born:"701"});
Za pomocą metody
sortOn()
można posortować obiekt Array według właściwości
born
. Metoda
sortOn()
definiuje dwa parametry:
fieldName
i
options
. Argument
fieldName
musi zostać określony jako ciąg. W poniższym przykładzie metoda
sortOn()
jest wywoływana z dwoma argumentami:
"born"
oraz
Array.NUMERIC
. Argument
Array.NUMERIC
jest używany w celu zapewnienia, że sortowanie zostało wykonane liczbowo, nie zaś alfabetycznie. Jest to dobra praktyka, nawet, jeśli wszystkie liczby mają taką samą liczbę cyfr, ponieważ zapewnia kontynuowanie sortowania zgodnie z oczekiwaniami, nawet już po późniejszym dodaniu większej lub mniejszej liczby cyfr do tablicy.
poets.sortOn("born", Array.NUMERIC);
for (var i:int = 0; i < poets.length; ++i)
{
trace(poets[i].name, poets[i].born);
}
/* output:
Wang 701
Dante 1265
Blake 1757
cummings 1894
Angelou 1928
*/
Sortowanie bez modyfikowania tablicy oryginalnej (tylko klasa Array)
Zwykle metody
sort()
i
sortOn()
modyfikują obiekt Array. Aby posortować obiekt Array bez modyfikowania istniejącej tablicy, należy przekazać stałą
Array.RETURNINDEXEDARRAY
jako część parametru
options
. Opcja ta żąda, by metody zwracały nowy obiekt Array, który odzwierciedla sortowanie, a pozostawiały oryginalny obiekt Array niezmieniony. Obiekt Array zwrócony za pomocą jednej z metod jest prostym obiektem Array zawierającym numery indeksów, które odpowiadają nowemu porządkowi sortowania, i nie zawiera żadnych elementów z oryginalnego obiektu Array. Aby na przykład możliwe było posortowanie obiektu
poets
klasy Array według roku urodzenia bez modyfikowania tablicy, należy włączyć stałą
Array.RETURNINDEXEDARRAY
jako część argumentu przekazanego dla parametru
options
.
W poniższym przykładzie zwracane informacje o indeksach zapisywane są w obiekcie Array o nazwie
indices
. Następnie tablica
indices
w połączeniu z niezmienioną tablicą
poets
jest używana do wygenerowania wyników w kolejności roku urodzenia.
var indices:Array;
indices = poets.sortOn("born", Array.NUMERIC | Array.RETURNINDEXEDARRAY);
for (var i:int = 0; i < indices.length; ++i)
{
var index:int = indices[i];
trace(poets[index].name, poets[index].born);
}
/* output:
Wang 701
Dante 1265
Blake 1757
cummings 1894
Angelou 1928
*/
Zapytania dotyczące tablic
Cztery metody klas Array i Vector —
concat()
,
join()
,
slice()
i
toString()
— wyszukują w tablicy informacje, ale nie modyfikują tablicy. Metody
concat()
i
slice()
zwracają nowe tablice. Metody
join()
i
toString()
zwracają ciągi. Metoda
concat()
pobiera nową tablicę lub listę elementów w postaci argumentów i łączy ją z istniejącą tablicą w celu utworzenia nowej tablicy. Metoda
slice()
ma dwa parametry o nazwach
startIndex
oraz
endIndex
. Zwraca nową tablicę zawierającą kopie elementów powycinanych z istniejącej tablicy. Warstwa ta zaczyna się od elementu
startIndex
, a kończy elementem poprzedzającym
endIndex
. Należy pamiętać, że element na pozycji
endIndex
nie jest uwzględniany w wartości zwracanej.
Poniższy przykład ilustruje używanie metod
concat()
oraz
slice()
do tworzenia nowych tablic przy użyciu elementów innych tablic.
var array1:Array = ["alpha", "beta"];
var array2:Array = array1.concat("gamma", "delta");
trace(array2); // output: alpha,beta,gamma,delta
var array3:Array = array1.concat(array2);
trace(array3); // output: alpha,beta,alpha,beta,gamma,delta
var array4:Array = array3.slice(2,5);
trace(array4); // output: alpha,beta,gamma
Korzystając z metod
join()
oraz
toString()
, można zwracać zawartość tablic w postaci ciągów. Jeśli dla metody
join()
nie są używane żadne parametry, te dwie metody zachowują się identycznie, zwracając ciąg zawierający listę rozdzielaną przecinkami, składającą się ze wszystkich elementów w tablicy. Metoda
join()
w przeciwieństwie do metody
toString()
przyjmuje parametr o nazwie
delimiter
, pozwalający wybrać symbol, który będzie rozdzielał poszczególne elementy w zwracanym ciągu.
W poniższym przykładzie tworzony jest obiekt Array o nazwie
rivers
oraz wywoływane są metody
join()
i
toString()
zwracające wartości z obiektu Array w postaci ciągu. Metoda
toString()
służy do zwracania wartości rozdzielanych przecinkami (
riverCSV
), podczas gdy metoda
join()
służy do zwracania wartości rozdzielanych znakiem
+
.
var rivers:Array = ["Nile", "Amazon", "Yangtze", "Mississippi"];
var riverCSV:String = rivers.toString();
trace(riverCSV); // output: Nile,Amazon,Yangtze,Mississippi
var riverPSV:String = rivers.join("+");
trace(riverPSV); // output: Nile+Amazon+Yangtze+Mississippi
Jedną z kwestii, jakie należy mieć na uwadze w przypadku posługiwania się metodą
join()
, jest to, że wszelkie zagnieżdżone wystąpienia klas Array lub Vector są zawsze zwracane w postaci rozdzielanej przecinkami, niezależnie od tego, jaki separator wybrano dla elementów tablicy głównej. Ilustruje to poniższy przykład.
var nested:Array = ["b","c","d"];
var letters:Array = ["a",nested,"e"];
var joined:String = letters.join("+");
trace(joined); // output: a+b,c,d+e
|
|
|