Пример массивов: PlayList

Flash Player 9 и более поздних версий, Adobe AIR 1.0 и более поздних версий

В примере PlayList показаны техники работы с массивами в контексте приложения, управляющего списками воспроизведения песен. Рассматриваются следующие техники:

  • создание индексного массива;

  • добавление элементов в индексный массив;

  • сортировка массива объектов по различным свойствам с помощью нескольких параметров сортировки;

  • преобразование массива в строку значений, разделенных заданным символом.

Получить файлы приложения для этого примера можно на странице www.adobe.com/go/learn_programmingAS3samples_flash_ru . Файлы приложения PlayList находятся в каталоге Samples/PlayList. Приложение состоит из следующих файлов.

File

Описание

PlayList.mxml

или

PlayList.fla

Основной файл приложения Flash (FLA) или Flex (MXML).

com/example/programmingas3/playlist/PlayList.as

Класс, отвечающий за отображение списка композиций. Для хранения списка данный класс использует Array. Он также отвечает за сортировку элементов списка.

com/example/programmingas3/playlist/Song.as

Объект значения, представляющий информацию об отдельной песне. Элементы, управляемые классом PlayList, являются экземплярами Song.

com/example/programmingas3/playlist/SortProperty.as

Псевдоперечисление, доступные значения которого представляют свойства класса Song, по которым сортируются объекты Song в списке.

Обзор класса PlayList

Класс PlayList управляет набором объектов Song. У него есть публичные методы с функциональностью, поддерживающей добавление песен в список воспроизведения (метод addSong() ) и их сортировку в списке (метод sortList() ). Кроме того, класс включает свойство доступа только для чтения, songList , позволяющее подключаться к действительному списку песен в списке воспроизведения. Внутри класса PlayList песни отслеживаются с помощью частной переменной Array:

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

Кроме переменной Array _songs , которая используется классом PlayList для отслеживания списка песен, две другие частные переменные отслеживают, нужно ли сортировать список ( _needToSort ), и какое свойство нужно использовать для сортировки в заданное время ( _currentSort ).

Как и в случае всех остальных объектов, объявление экземпляра Array — это лишь половина успеха в деле создания массива. Прежде чем пользоваться свойствами или методами экземпляра Array, необходимо создать экземпляр с помощью конструктора класса PlayList.

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

Первая строка конструктора создает экземпляр переменной _songs , которая готова к использованию. Кроме того, для установки начального свойства сортировки вызывается метод sortList() .

Добавление песни в список

Когда пользователь добавляет в приложение новую песню, код в элементе данных вызывает метод класса PlayList addSong() .

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

Внутри метода addSong() вызывается метод push() массива _songs , который добавляет объект Song, переданный методу addSong() , в качестве нового элемента массива. Метод push() добавляет новый элемент в конец массива независимо от того, выполнялась ли ранее сортировка массива. Это означает, что после вызова метода push() список песен вряд ли будет отсортирован правильно, поэтому нужно задать переменной _needToSort значение true . В теории метод sortList() можно вызвать незамедлительно, благодаря чему не нужно будет отслеживать, отсортирован ли список в тот или иной момент времени. Однако на практике список песен нужно сортировать лишь непосредственно перед тем, как к нему обратятся. Отказываясь от сортировки, приложение пропускает ненужные операции, например, в случае, если к списку до обращения было добавлено несколько песен.

Сортировка списка песен

Так как экземпляры Song, которыми управляет список воспроизведения, являются сложными объектами, пользователям приложения может потребоваться выполнить сортировку списка песен по разным свойствам, например по названию или по году выпуска. В приложении PlayList задача сортировки списка песен состоит из трех частей: определение свойства, по которому выполняется сортировка; определение параметров сортировки при сортировке по этому свойству; выполнение собственно операции сортировки.

Свойства сортировки

Объект Song отслеживает некоторые свойства, включая название песни, имя исполнителя, год выпуска, имя файла и жанр песни, который выбирает сам пользователь. Для сортировки подходят только первые три. Для удобства разработчиков в пример включен класс SortProperty, действующий как перечисление со значениями, представляющими свойства для сортировки.

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

Класс SortProperty содержит три переменные: TITLE , ARTIST и YEAR , в каждой из которых хранится строка с именем связанного свойства класса Song, используемого при сортировке. В остальном коде свойство сортировки определяется с помощью члена перечисления. Например, в конструкторе PlayList список изначально сортируется путем вызова метода sortList() , как показано ниже:

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

Свойство сортировки задано в форме SortProperty.TITLE , поэтому песни сортируются по названию.

Сортировка по свойству и установка свойств сортировки

Сама сортировка выполняется классом PlayList в методе 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; 
    }

При сортировке по названию или имени исполнителя имеет смысл следовать алфавитному порядку, но при сортировке по году выпуска разумнее использовать числовой порядок. Инструкция switch используется для определения подходящего параметра сортировки, хранящегося в переменной sortOptions , о чем говорит значение, заданное в параметре sortProperty . Здесь члены перечисления снова используются для различения свойств, а не жестко заданных значений.

Когда параметры и свойства сортировки определены, массив _songs сортируется путем вызова метода sortOn() , который передает эти два значения в качестве параметров. Записывается текущее свойство сортировки, а также фиксируется сам факт сортировки.

Объединение элементов массива в строку значений, разделенных символом

Массив в данном примере используется не только для хранения списка песен в классе PlayList, но и для управления списком жанров песен в классе Song. Обратите внимание на следующий фрагмент кода из определения класса 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(";"); 
}

При создании нового экземпляра Song параметр genres , используемый для указания жанра (или жанров) песни, определяется как экземпляр Array. Это упрощает группировку нескольких жанров в единую переменную, которую затем можно передавать конструктору. Тем не менее, внутри класса Song жанры хранятся в частной переменной _genres в виде экземпляра String со значениями, разделенными точкой с запятой. Параметр Array преобразуется в строку значений, разделенных точкой с запятой, путем вызова метода join() со значением литерала строки ";" в качестве разделителя.

По такому же принципу методы доступа genres поддерживают установку или извлечение жанров в виде массива:

    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(";"); 
    }

Метод доступа genres set работает как конструктор: он принимает массив и вызывает метод join() для преобразования массива в строку значений, разделенных точкой с запятой. Метод доступа get выполняет обратную операцию: вызывается метод split() переменной _genres , и строка разбивается на массив значений с помощью заданного разделителя (литералом строки, как и прежде, является символ ";" ).