Московский физико-технический институт
Опубликован: 23.12.2005 | Доступ: свободный | Студентов: 2867 / 252 | Оценка: 4.61 / 4.44 | Длительность: 27:18:00
ISBN: 978-5-9556-0051-2
Лекция 4:

Контейнеры

Эмуляция стека, очереди и хэш-таблицы

Как мы уже говорили, массив во Флэше многофункциональный и позволяет эмулировать многие другие структуры данных. Специальных методов в массиве нет лишь для эмуляции хэш-таблицы - но своего рода хэш-таблицей является во Флэше любой объектный тип, так что и с этой задачей массив справляется. Давайте рассмотрим по порядку, что и как можно эмулировать.

Эмуляция списка

Функциональность списка эмулируется при помощи методов splice, slice и concat. Собственно говоря, специфичной для списка является легкость удаления и вставки элементов, а также простота перемещения маркеров начала и конца списка. (Вообще-то изменение положений начала и конца сводится к удалению элементов, и мы отдельно упомянули об этом только потому, что выделить подсписок, точнее даже его копию, во Флэше мы можем с помощью отдельного метода.) Кроме того, легко сцепить два маленьких списка в один большой. Все только что перечисленное можно делать, используя вместо списка объект Array.

Начнем с удаления и вставки элементов. В объекте Array для этого служит метод splice, название которого переводится как "соединять внахлест" - например, магнитную ленту. (Есть, конечно, и другие переводы, но этот - самый подходящий.) В этот метод может передаваться произвольное количество аргументов. Первый аргумент - индекс элемента, начиная с которого надо производить удаление. Второй - количество удаляемых элементов (это может быть ноль). Последующие аргументы - это элементы, которые надо вставить на место удаленных. Возвращает метод splice субмассив удаленных элементов (а вовсе не "ничего", как написано в онлайн-документации). Вот пример его работы: следующий код

a_array = ["zero", "one", "two", "three", "four"];
trace("Splice returns: " + a_array.splice(1, 3, 0, 1, 2));
trace("a_array: " + a_array);
trace("---------------");
trace("Splice returns: " + a_array.splice(1, 0, 0, 1, 2));
trace("a_array: " + a_array);

выводит в консоль

Splice returns: one,two,three
a_array: zero,0,1,2,four
---------------
Splice returns:
a_array: zero,0,1,2,0,1,2,four

Отметим, что если из массива ничего не удаляется, то первый из вставленных элементов будет иметь номер, указанный в первом аргументе метода splice.

Следующий метод, который мы рассмотрим - это slice. Он принимает два аргумента: индекс начала субмассива и индекс конца. Причем, элемент, имеющий индекс конца, в возвращаемый субмассив не включается. В отличие от splice, метод slice не изменяет исходный массив. Иллюстрирующий все это пример

a_array = ["zero", "one", "two", "three", "four"];
trace("Slice returns: " + a_array.slice(2, 4));
trace("a_array = " + a_array);
trace("The biggest slice: " + a_array.slice(0, a_array.length));

выводит в консоль

Slice returns: two,three
a_array = zero,one,two,three,four
The biggest slice: zero,one,two,three,four

Обратите внимание: последний вариант применения slice - в вызове a_array.slice(0, a_array.length) - позволяет нам получить копию массива.

Наконец, рассмотрим метод concat. Этот метод соединяет в один массив произвольное количество объектов и других массивов. Исходный массив (у которого был вызван метод concat ) при этом не изменяется; в результирующем массиве его элементы идут первыми, а затем уже следуют элементы массивов (или единичные объекты), которые были переданы в аргументах метода. Вот пример работы метода concat:

a_array = ["zero", "one", "two", "three", "four"];
b_array = a_array.concat(3, ["a", "b"], 10, [0, [1, 2], 3]);
trace("a_array = " + a_array);
trace("b_array = " + b_array);
trace("b_array[10] = " + b_array[10]);

На выходе получаем:

a_array = zero,one,two,three,four
b_array = zero,one,two,three,four,3,a,b,10,0,1,2,3
b_array[10] = 1,2

Обратите внимание на последний вызов trace. Мы проверили, что массив, вложенный в другой, не "раскрывается", то есть не разбивается на отдельные элементы при вызове concat.

Эмуляция стека

С эмуляцией стека ни малейших проблем не предвидится, поскольку в классе Array есть методы push и pop. Единственный вопрос, который может возникнуть, - если мы захотим совместить функциональность стека и функциональность массива, где нам искать элементы, помещенные в массив при помощи push? В начале или в конце массива? Давайте проверим это с помощью следующего кода:

electro_array = ["Резистор", "Диод"];
trace(electro_array.push("Транзистор", "Тиристор", "Дроссель"));
trace(electro_array);
trace(electro_array.pop());
trace(electro_array);

На выходе получаем:

5
Резистор,Диод,Транзистор,Тиристор,Дроссель
Дроссель
Резистор,Диод,Транзистор,Тиристор

Итак, элементы добавляются в конец массива (причем можно добавлять сразу несколько элементов), метод push возвращает длину массива, получившегося в результате.