Associatieve arrays

Flash Player 9 of hoger, Adobe AIR 1.0 of hoger

Een associatieve array, die ook wel een hash of map wordt genoemd, gebruikt sleutels in plaats van een numerieke index om opgeslagen waarden te ordenen. Elke sleutel in een associatieve array is een unieke tekenreeks die toegang geeft tot een opgeslagen waarde. Een associatieve array is een instantie van de klasse Object, wat wil zeggen dat elke sleutel overeenkomt met een eigenschapnaam. Associatieve arrays zijn ongeordende verzamelingen van sleutel- en waardeparen. In de code wordt er niet vanuit gegaan dat de sleutels van een associatieve array in een specifieke volgorde staan.

ActionScript 3.0 bevat eveneens een geavanceerd type van associatieve arrays, die woordenboeken worden genoemd. Woordenboeken, instanties van de klasse Dictionary in het pakket flash.utils, werken met sleutels die elk willekeurig gegevenstype kunnen hebben. Woordenboeksleutels zijn met andere woorden niet beperkt tot waarden van het type String.

Associatieve arrays met tekenreekssleutels

Er zijn twee manieren om associatieve arrays te maken in ActionScript 3.0. De eerste manier is met behulp van een Object-instantie. Met een Object-instantie kunt u de array initialiseren met een objectliteraal. Een instantie van de klasse Object, ook een algemeen object genoemd, is functioneel gezien identiek aan een associatieve array. Elke eigenschapnaam van het algemene object wordt gebruikt als de sleutel die toegang geeft tot een opgeslagen waarde.

In het volgende voorbeeld wordt een associatieve array gemaakt met de naam monitorInfo en daarbij wordt een letterlijk teken voor objecten gebruikt om de array te initialiseren met twee sleutel- en waardeparen.

var monitorInfo:Object = {type:"Flat Panel", resolution:"1600 x 1200"}; 
trace(monitorInfo["type"], monitorInfo["resolution"]);  
// output: Flat Panel 1600 x 1200

Als u de array niet hoeft te declareren op het declaratietijdstip, kunt u de constructor Object gebruiken om de array te maken. Dit gaat als volgt:

var monitorInfo:Object = new Object();

Nadat de array is gemaakt met een objectliteraal of de constructor van de klasse Object, kunt u nieuwe waarden aan de array toevoegen met de operator voor arraytoegang ( [] ) of de puntoperator ( . ). In het volgende voorbeeld worden twee nieuwe waarden toegevoegd aan monitorArray :

monitorInfo["aspect ratio"] = "16:10"; // bad form, do not use spaces 
monitorInfo.colors = "16.7 million"; 
trace(monitorInfo["aspect ratio"], monitorInfo.colors); 
// output: 16:10 16.7 million

De sleutel met de naam aspect ratio bevat een spatieteken. Dit is mogelijk wanneer u de operator voor arraytoegang ( [] ) gebruikt. Er wordt echter een fout gegenereerd als u dit probeert met de puntoperator. Het gebruik van spaties in sleutelnamen wordt afgeraden.

De tweede manier om een associatieve array te maken is de Array-constructor (of de constructor van een willekeurige dynamische klasse) te gebruiken en vervolgens de operator voor arraytoegang ( [] ) of de puntoperator ( . ) te gebruiken om sleutel- en waardeparen aan de array toe te voegen. Als u uw associatieve array als type Array declareert, kunt u geen letterlijk teken voor objecten gebruiken om de array te initialiseren. In het volgende voorbeeld wordt een associatieve array met de naam monitorInfo gemaakt met de constructor Array en worden een sleutel met de naam type en een sleutel met de naam resolution toegevoegd, samen met hun waarden:

var monitorInfo:Array = new Array(); 
monitorInfo["type"] = "Flat Panel"; 
monitorInfo["resolution"] = "1600 x 1200"; 
trace(monitorInfo["type"], monitorInfo["resolution"]);  
// output: Flat Panel 1600 x 1200

Het biedt geen voordelen de constructor Array te gebruiken om een associatieve array te maken. U kunt de eigenschap Array.length of de methoden uit de klasse Array niet gebruiken met associatieve arrays, zelfs bij gebruik van de constructor Array of het gegevenstype Array. De constructor Array is het meest geschikt voor het maken van geïndexeerde arrays.

Geassocieerde arrays met objectsleutels (Woordenboeken)

Met de klasse Dictionary kunt u een associatieve array maken die objecten als sleutel gebruikt in plaats van tekenreeksen. Dergelijke arrays worden soms dictionary’s, hashes of maps genoemd. Neem bijvoorbeeld een toepassing die de locatie van een object Sprite bepaalt op basis van zijn associatie met een specifieke container. Met een object Dictionary kunt u elk object Sprite aan een container koppelen.

Met de volgende code worden drie instanties van de klasse Sprite gemaakt die dienen als sleutel voor het object Dictionary. Elke sleutel krijgt een waarde toegewezen uit GroupA of GroupB . De waarden kunnen van elk gegevenstype zijn, maar in dit voorbeeld is zowel GroupA als GroupB een instantie uit de klasse Object. U kunt de waarde die aan de sleutels is gekoppeld, benaderen met de operator voor arraytoegang ( [] ), zoals in de volgende code wordt getoond:

import flash.display.Sprite; 
import flash.utils.Dictionary; 
 
var groupMap:Dictionary = new Dictionary(); 
 
// objects to use as keys 
var spr1:Sprite = new Sprite(); 
var spr2:Sprite = new Sprite(); 
var spr3:Sprite = new Sprite(); 
 
// objects to use as values 
var groupA:Object = new Object(); 
var groupB:Object = new Object(); 
 
// Create new key-value pairs in dictionary. 
groupMap[spr1] = groupA; 
groupMap[spr2] = groupB; 
groupMap[spr3] = groupB; 
 
if (groupMap[spr1] == groupA) 
{ 
    trace("spr1 is in groupA");  
} 
if (groupMap[spr2] == groupB) 
{ 
    trace("spr2 is in groupB");  
} 
if (groupMap[spr3] == groupB) 
{ 
    trace("spr3 is in groupB");  
}

Doorlopen met objectsleutels

U kunt de inhoud van een object Dictionary doorlopen met een lus for..in of een lus for each..in de lus. Met een lus for..in kunt u de inhoud doorlopen op basis van de sleutels en met een lus for each..in kunt u de inhoud doorlopen op basis van de waarden die aan elke sleutel zijn gekoppeld.

Gebruik de lus for..in voor directe toegang tot de objectsleutels van een object Dictionary. U kunt ook de waarden van het Dictionary-object benaderen met de operator voor arraytoegang ( [] ). In de volgende code wordt het vorige voorbeeld van de dictionary groupMap gebruikt om aan te geven hoe u een object Dictionary doorloopt met de lus for..in de lus :

for (var key:Object in groupMap) 
{ 
    trace(key, groupMap[key]); 
} 
/* output: 
[object Sprite] [object Object] 
[object Sprite] [object Object] 
[object Sprite] [object Object] 
*/

Gebruik de lus for each..in voor directe toegang tot de waarden van een object Dictionary. In de volgende code wordt ook de dictionary groupMap gebruikt om aan te geven hoe u een object Dictionary doorloopt met de lus for each..in de lus :

for each (var item:Object in groupMap) 
{ 
    trace(item); 
} 
/* output: 
[object Object] 
[object Object] 
[object Object] 
*/

Objectsleutels en geheugenbeheer

Adobe® Flash® Player en Adobe® AIR™ gebruiken een opschoonsysteem om geheugen vrij te maken dat niet meer in gebruik is. Wanneer niet meer naar een object wordt verwezen, kan het worden opgeschoond. De volgende keer dat de opschoonfunctie wordt uitgevoerd, wordt geheugen vrijgemaakt. In de volgende code wordt bijvoorbeeld een nieuw object gemaakt en wordt een verwijzing naar het object toegewezen aan de variabele myObject :

var myObject:Object = new Object();

Zolang er verwijzingen naar het object bestaan, maakt de opschoonfunctie het geheugen dat het object in beslag neemt, niet vrij. Als de waarde van myObject zodanig wordt gewijzigd dat er een verwijzing naar een ander object ontstaat of dat de waarde null wordt, komt het geheugen dat door het oorspronkelijke object wordt ingenomen in aanmerking om te worden opgeschoond, maar alleen als er geen andere verwijzingen naar het oorspronkelijke object bestaan.

Als u myObject gebruikt als sleutel in een object Dictionary, maakt u nog een verwijzing naar het oorspronkelijke object. In de volgende code worden bijvoorbeeld twee verwijzingen naar een object gemaakt, de variabele myObject en de sleutel in het object myMap :

import flash.utils.Dictionary; 
 
var myObject:Object = new Object(); 
var myMap:Dictionary = new Dictionary(); 
myMap[myObject] = "foo";

Als u het object waarnaar wordt verwezen door myObject wilt laten opschonen, moet u alle verwijzingen ernaar verwijderen. In dit geval moet u de waarde myObject wijzigen en de sleutel myObject verwijderen uit myMap , zoals in de volgende code wordt getoond:

myObject = null; 
delete myMap[myObject];

U kunt echter ook de parameter useWeakReference van de constructor Dictionary gebruiken om van alle dictionarysleutels een zogenaamde zwakke verwijzing te maken. Zwakke verwijzingen worden door het opschoonsysteem genegeerd, wat betekent dat een object met alleen zwakke verwijzingen voor opschonen in aanmerking komt. In de volgende code hoeft u bijvoorbeeld de sleutel myObject niet te verwijderen uit myMap om het object te laten opschonen:

import flash.utils.Dictionary; 
 
var myObject:Object = new Object(); 
var myMap:Dictionary = new Dictionary(true); 
myMap[myObject] = "foo"; 
myObject = null; // Make object eligible for garbage collection.