Voorbeeld van arrays: PlayList

Flash Player 9 of hoger, Adobe AIR 1.0 of hoger

In het voorbeeld PlayList worden technieken voor het werken met arrays gedemonstreerd in de context van een muziekspeler waarin een lijst met nummers wordt beheerd. Deze technieken zijn:

  • Een geïndexeerde array maken

  • Items toevoegen aan een geïndexeerde array

  • Een array van objecten sorteren op verschillende eigenschappen met behulp van verschillende sorteeropties

  • Een array omzetten in een tekenreeks met een teken als scheidingsteken

Zie www.adobe.com/go/learn_programmingAS3samples_flash_nl als u de toepassingsbestanden voor dit voorbeeld wilt downloaden. U vindt de bestanden voor de PlayList-toepassing in de map Samples/PlayList. De toepassing bestaat uit de volgende bestanden:

Bestand

Beschrijving

PlayList.mxml

of

PlayList.fla

Het hoofdtoepassingsbestand in Flash (FLA) of Flex (MXML).

com/example/programmingas3/playlist/PlayList.as

Een klasse die een lijst met nummers voorstelt. Deze gebruikt een Array om de lijst op te slaan, en beheert de sortering van de items in de lijst.

com/example/programmingas3/playlist/Song.as

Een waardeobject voor informatie over een nummer. De items die door de klasse PlayList worden beheerd, zijn instanties van Song.

com/example/programmingas3/playlist/SortProperty.as

Een pseudo-opsomming waarvan de beschikbare waarden de eigenschappen van de klasse Song voorstellen aan de hand waarvan een lijst met objecten van het type Song kan worden gesorteerd.

Overzicht van de klasse PlayList

De klasse PlayList beheert een set objecten van het type Song. Deze klasse heeft methoden van het type public met functionaliteit voor het toevoegen van een nummer aan de afspeellijst (de methode addSong()) en voor het sorteren van de nummers in de lijst (de methode sortList()). Bovendien bevat deze klasse een eigenschap voor alleen-lezen-toegang (songList) voor toegang tot de eigenlijke set nummers in de afspeellijst. Intern houdt de klasse PlayList de nummers bij met behulp van een Array-variabele van het type private:

public class PlayList 
{ 
    private var _songs:Array; 
    private var _currentSort:SortProperty = null; 
    private var _needToSort:Boolean = false; 
    ... 
}

Naast de Array-variabele _songs, die door de klasse PlayList wordt gebruikt om de eigen lijst met nummers bij te houden, houden twee andere private variabelen bij of de lijst moet worden gesorteerd (_needToSort) en aan de hand van welke eigenschap de lijst met nummers moet worden gesorteerd op een bepaald moment (_currentSort).

Zoals bij alle objecten is het declareren van een instantie Array nog maar de helft van het maken van een array. Voordat de eigenschappen of methoden van een instantie Array kunnen worden benaderd, moet van de array een instantie worden gemaakt met behulp van de constructor van de klasse PlayList.

    public function PlayList() 
    { 
        this._songs = new Array(); 
        // Set the initial sorting. 
        this.sortList(SortProperty.TITLE); 
    }

De eerste regel van de constructor maakt een instantie van de variabele _songs, zodat deze klaar is voor gebruik. Vervolgens wordt de methode sortList() aangeroepen om de eerste eigenschap waarop wordt gesorteerd te bepalen.

Een nummer aan de lijst toevoegen

Wanneer een gebruiker een nieuw nummer aan de toepassing toevoegt, roept de code in het gegevensinvoerformulier de methode addSong() van de klasse PlayList aan.

    /** 
     * Adds a song to the playlist. 
     */ 
    public function addSong(song:Song):void 
    { 
        this._songs.push(song); 
        this._needToSort = true; 
    }

In addSong() wordt de methode push() van de array _songs aangeroepen, waardoor het object Song dat aan addSong() is doorgegeven, als nieuw element aan die array wordt toegevoegd. Met de methode push() wordt het nieuwe element aan het einde van de array toegevoegd, ongeacht de eventueel eerder toegepaste sorteervolgorde. Dit betekent dat na het aanroepen van de methode push() de sorteervolgorde van de lijst met nummers waarschijnlijk niet meer klopt. Daarom wordt de variabele _needToSort op true ingesteld. In theorie kan onmiddellijk de methode sortList() worden aangeroepen, zodat niet meer hoeft te worden bijgehouden of de lijst op een bepaald moment al dan niet gesorteerd is. In de praktijk hoeft de lijst met nummers echter pas net vóór het opvragen te worden gesorteerd. Door het sorteren uit te stellen hoeft de toepassing niet onnodig te sorteren als bijvoorbeeld meerdere nummers aan de lijst worden toegevoegd vóór het opvragen.

De lijst met nummers sorteren

Omdat de instanties Song die door de afspeellijst worden beheerd complexe objecten zijn, willen de gebruikers van de toepassing de afspeellijst misschien liever sorteren op andere eigenschappen, zoals de naam van het nummer of het jaar waarin het is uitgebracht. In de toepassing PlayList bestaat het sorteren van de lijst met nummers uit drie onderdelen: de eigenschap identificeren waarop de lijst moet worden gesorteerd, aangeven welke sorteeropties gebruikt moeten worden wanneer er op die eigenschap wordt gesorteerd en het daadwerkelijk uitvoeren van de sorteerbewerking.

Eigenschappen om op te sorteren.

Een object van het type Song houdt verschillende eigenschappen bij, waaronder de titel van het nummer, de artiest, het jaar waarin het nummer is uitgebracht, de bestandsnaam en een door de gebruiker geselecteerde verzameling genres waartoe het nummer behoort. Hiervan zijn alleen de eerste drie handig om op te sorteren. Om het de ontwikkelaars gemakkelijker te maken wordt in het voorbeeld de klasse SortProperty gebruikt, die fungeert als opsomming met waarden voor de eigenschappen waarop kan worden gesorteerd.

    public static const TITLE:SortProperty = new SortProperty("title"); 
    public static const ARTIST:SortProperty = new SortProperty("artist"); 
    public static const YEAR:SortProperty = new SortProperty("year");

De klasse SortProperty bevat drie constanten (TITLE, ARTIST en YEAR). In elk van deze constanten wordt een tekenreeks opgeslagen met de werkelijke naam van de bijbehorende eigenschap van de klasse Song waarop kan worden gesorteerd. In de rest van de code worden sorteereigenschappen aangegeven met het lid van de opsomming. In de constructor PlayList wordt bijvoorbeeld de lijst in eerste instantie gesorteerd door de methode sortList() aan te roepen:

        // Set the initial sorting. 
        this.sortList(SortProperty.TITLE);

Omdat de eigenschap om op te sorteren wordt aangegeven als SortProperty.TITLE, worden de nummers gesorteerd op titel.

Sorteren op eigenschap en sorteeropties opgeven

Het eigenlijke sorteren van de lijst met nummers wordt uitgevoerd door de klasse PlayList in de methode sortList():

    /** 
     * Sorts the list of songs according to the specified property. 
     */ 
    public function sortList(sortProperty:SortProperty):void 
    { 
        ... 
        var sortOptions:uint; 
        switch (sortProperty) 
        { 
            case SortProperty.TITLE: 
                sortOptions = Array.CASEINSENSITIVE; 
                break; 
            case SortProperty.ARTIST: 
                sortOptions = Array.CASEINSENSITIVE; 
                break; 
            case SortProperty.YEAR: 
                sortOptions = Array.NUMERIC; 
                break; 
        } 
         
        // Perform the actual sorting of the data. 
        this._songs.sortOn(sortProperty.propertyName, sortOptions); 
             
        // Save the current sort property. 
        this._currentSort = sortProperty; 
 
        // Record that the list is sorted. 
        this._needToSort = false; 
    }

Bij het sorteren op titel of artiest is alfabetisch sorteren handig, maar bij het sorteren op jaar is numeriek sorteren logischer. Met de instructie switch wordt de juiste sorteeroptie gedefinieerd, opgeslagen in de variabele sortOptions, op basis van de waarde die is vastgelegd in de parameter sortProperty. Opnieuw worden hier de benoemde leden van de opsomming gebruikt om onderscheid te maken tussen de eigenschappen (in plaats van hard gecodeerde waarden).

Wanneer de sorteereigenschap en sorteeropties zijn bepaald, wordt de array _songs pas echt gesorteerd door de methode sortOn() aan te roepen, waarbij die twee waarden als parameter worden doorgegeven. De huidige sorteereigenschap wordt vastgelegd, evenals het feit dat de lijst met nummers nu is gesorteerd.

Arrayelementen omzetten in een tekenreeks met een teken als scheidingsteken

Naast het gebruik van een array om de lijst met nummers bij te houden in de klasse PlayList, worden in dit voorbeeld ook arrays gebruikt in de klasse Song als hulpmiddel bij het beheer van de lijst met genres waartoe een bepaald nummer behoort. Bekijk het volgende fragment uit de definitie van de klasse Song:

private var _genres:String; 
 
public function Song(title:String, artist:String, year:uint, filename:String, genres:Array) 
{ 
    ... 
    // Genres are passed in as an array 
    // but stored as a semicolon-separated string. 
    this._genres = genres.join(";"); 
}

Wanneer een nieuwe instantie Song wordt gemaakt, wordt de parameter genres voor het opgeven van het genre (of de genres) van het nummer gedefinieerd als een instantie van het type Array. Dit maakt het gemakkelijker om meerdere genres te groeperen in één variabele die aan de constructor kan worden doorgegeven. Intern houdt de klasse Song de genres echter bij in de variabele van het type private _genres als instantie van het type String met een puntkomma als scheidingsteken. De parameter Array wordt omgezet in een tekenreeks met een puntkomma als scheidingsteken door de bijbehorende methode join() aan te roepen met de letterlijke tekenreekswaarde ";" als opgegeven scheidingsteken.

Op dezelfde manier kunnen met de accessors van het type genres genres worden ingesteld of opgevraagd als Array:

    public function get genres():Array 
    { 
        // Genres are stored as a semicolon-separated String, 
        // so they need to be transformed into an Array to pass them back out. 
        return this._genres.split(";"); 
    } 
    public function set genres(value:Array):void 
    { 
        // Genres are passed in as an array, 
        // but stored as a semicolon-separated string. 
        this._genres = value.join(";"); 
    }

De accessor genresset gedraagt zich op precies dezelfde manier als de constructor: hij accepteert een Array en roept de methode join() aan voor de omzetting in een tekenreeks met een puntkomma als scheidingsteken. De accessor get voert een tegenovergestelde bewerking uit: de methode split() van de variabele _genres wordt aangeroepen, waardoor de String wordt opgedeeld in een array van waarden met het opgegeven scheidingsteken (dezelfde letterlijke tekenreekswaarde ";" als daarvoor).