Tra le novità introdotte nel Flash Player 10 (e nella CS4), se ne annovera una molto interessante per gli sviluppatori, benchè poco conosciuta e "pubblicizzata": si tratta del tipo di oggetto Vector, che può essere considerato un "parente" dell'Array
e che, in molti casi, può sostituirlo con miglioramenti, anche notevoli, a livello di performance.
In questo articolo esaminiamo i punti in comune e le princiapli differenze tra Vector
ed Array
.
Nota: l'oggetto Vector
è disponibile solo in ActionScript 3 ed è compatibile solo con il Flash Player 10 e successivi.
Dichiarazione della variabile
La differenza più importante tra questi i due tipi risiede nel fatto che Array può contenere diversi tipi di oggetti, mentre Vector può contenere oggetti solo di un tipo (quindi solo numeri, o solo stringe, o solo Sprite, etc.) e questo tipo va specificato in fase di dichiarazione. Se per dichiarare un array è sufficiente la sintassi:
Nella dichiarazione di un vettore bisogna specificare il tipo di oggetto, in questo modo:
var vettore:Vector.<Number> = new Vector.<Number>()
In questo caso abbiamo definito un vettore con elementi di solo tipo numerico. Vediamo meglio cosa comporta questa differenza: usando un Array
var array:Array = new Array(); array[0] = "Ciao"; array[1] = 0; array[2] = root;
Non riceveremo errori di compilazione, e otterremo una collezione di tre diversi tipi di oggetto: una stringa ("ciao"
0
DisplayObject
root
Una operazione del genere non è possibile con un Vector
Number
var vettore:Vector.<Number> = new Vector.<Number>(); vettore[0] = "Ciao"; vettore[1] = 0; vettore[2] = root;
otterremo due errori di compilazione, uno per l'elemento stringa e uno per l'elemento DisplayObject
vettore
Ovviamente, oltre ai tipi del Flash Player, si può specificare come oggetto una classe personalizzata
Indici e lunghezza dell'oggetto
Un'altra differenza di cui tenere conto è una limitazione nell'uso degli indici: un Vector non può avere indici vuoti, cosa invece possibile per gli Array
. Anche in questo caso facciamo un piccolo esempio per capire meglio.
Questo codice sarà compilato senza errori, e se proviamo a stampare il valore dell'indice 1 di array
undefined
var vettore:Vector.<Number> = new Vector.<Number>(); vettore[0] = 1; vettore[2] = 3;
Otterremo un errore RangeError: Error #1125: L'indice 2 non è nell'intervallo 1
Il concetto è simile a quello della DisplayList
movieclip
sprite
Vector
Un'altra caratteristica che i Vector
Array
dichiarare il numero degli elementi
var vettore:Vector.<Number> = new Vector.<Number>(3); vettore[0] = 1; vettore[2] = 3;
dichiariamo un vettore
vettore[1]
0
String
undefined
Dichiarando il numero di elementi, quindi, popoliamo il vettore di n
vettore[3]
vettore[4]
// codice accettato e funzionante var vettore:Vector.<Number> = new Vector.<Number>(3); vettore[0] = 1; vettore[1] = 3; vettore[3] = 5; // genera un errore var vettore:Vector.<Number> = new Vector.<Number>(3); vettore[0] = 1; vettore[1] = 3; vettore[4] = 5;
Il fatto che venga accettata l'aggiunta di valore[3]
tale dimensione è dinamica
Come abbiamo accennato è anche possibile impostare l'oggetto in modo che il vettore abbia la lunghezza fissa
var vettore:Vector.<Number> = new Vector.<Number>(3, true);
In questo caso vettore
Number
La lunghezza fissa su un vettore si può attivare o disattivare anche in seguito grazie alla proprietà fixed
Chiavi testuali
Un'altra differenza sta nel fatto che Vector supporta solo indici numerici e non testuali. Per esempio possiamo popolare un Array
in questo modo:
Con Vector
Vector
Array
Object
var vettore:Vector.<Array> = new Vector.<Array>(); vettore[0] = new Array(); vettore[0]["ciao"] = "ciao"; vettore[0]["root"] = root;
ma, nella maggior parte dei casi, è un'operazione priva di senso. Possiamo considerare Vector
Array
Ordinamento dei valori
Un altro punto in cui queste due tipologie di oggetto sono sostanzialmente differenti è l'ordinamento degli elementi: sebbene il comando usato sia sempre sort
, nel caso di Vector è sempre necessario specificare una funzione di comparazione personalizzata. È una possibilità che si ha anche con Array
, tuttavia per questi ultimi esistono anche funzioni di ordinamento predefinite, invece se proviamo da applicare il comando sort
su un Vector
, questo non viene ordinato ma ne viene solo creata una copia identica.
Vediamo allora come usare una funzione personalizzata, per prima cosa creiamo il nostro Vector
che per semplificare faremo di tipo numerico.
Scriviamo quindi il codice per la comparazione:
var ordinato:Vector.<Number> = numeri.sort(ordinaNumerico); trace(ordinato); function ordinaNumerico(x:Number, y:Number):Number { if (x < y) { return -1; } else if (x > y) { return 1; } else { return 0; } }
Il vettore risulterà ordinato in ordine crescente, poiché nel caso di x<y
-1
1
x>y
invertire l'ordinamento
Punti in comune tra Array e Vector
Finora abbiamo visto le differenza tra array e vector, ma questi due tipi di oggetto hanno molti punti in comune, principalmente per quanto riguarda la manipolazione e le proprietà.
Aggiunta di uno o più elementi
Ad esempio, per aggiungere oggetti abbiamo a disposizione per entrambi i comandi push e unshift (oltre alla notazione [indice]
). Attenzione però, l'uso di questi due comandi con Vector nasconde un'insidia: il tipo dell'elemento che aggiungiamo alla collezione viene verificato solo a runtime. Ad esempio, il codice
restituisce un errore di compilazione rilevando il tipo di valore stringa di "ciao", mentre il codice
var vettore:Vector.= new Vector. (); vettore[0] = 2; vettore[1] = 4; vettore.push("ciao"); trace(vettore[2]);
viene eseguito senza errori, anche se poi come output otterremmo NaN
Ricavare il valore di un elemento
Come abbiamo visto, per ricavare un valore da un vettore e da un array si utilizza la notazione con le parentesi quadre. È possibile usare anche i metodi pop e shift, che rispettivamente ricavano e rimuovono l'ultimo e il primo elemento di un Array
o di un Vector
.
Ricavare il numero di elementi nell'oggetto
Anche in questo caso la proprietà da utilizzare è la medesima, infatti length
vale sia per Array
, sia per Vector
, va considerato però che per Vector
il valore è per certi versi "più attendibile" data l'impossibilità di usare indici "fuori intervallo", mentre con un array questo codice:
restituisce come output 6, quando in realtà abbiamo solo due elementi nel nostro array. Con Vector
Ricerca di elementi e manipolazione dell'oggetto
Tanto per un Array quanto per un Vector, è possibile usare i metodi IndexOf
e lastIndexOf
; analogamente, i comandi every
, some
, forEach
, map
e filter
sono disponibili per entrambi i tipi di oggetto e hanno funzionamento identico.
Conclusioni
Array
e Vector
sono molto simili. Potremmo dire che Vector
sia una sorta "mutazione" di Array
: ne eredita pressoché tutti i comandi e ne varia leggermente le caratteristiche, principalmente il fatto di poter contenere oggetti di un solo tipo. Questa potrebbe apparire una limitazione, ma è in realtà ciò che rende l'oggetto Vector
molto interessante: grazie a queste restrizioni Vector offre maggior sicurezza e soprattutto migliori prestazioni. Da alcuni
emerge un miglioramento della velocità di esecuzione anche del 60% rispetto ad Array.
L'unico caso in cui attualmente sembra che i Vector siano più lenti sono le operazioni di ordinamento, nelle altre operazioni invece Vector
risulta più veloce e spesso in maniera rilevante, aspetto che lo rende sicuramente molto utile nello sviluppo di applicazioni che prevedono molti calcoli.