Хорошие новости, все. Все, кто работает с массивами и векторами, а значит, и все разработчики, получат новые возможности: начиная с сборки Flash в конце августа 2011 года, Realaxy ActionScript Editor (RASE) поддерживает новое расширение языка Collections AS3. В этом посте мы покажем вам, на что он способен.
Коллекция — это общий термин, который примерно означает «группа объектов одинакового типа, сгруппированных вместе». Сборка коллекции в ActionScript 3.0 может быть выполнена с использованием массивов, векторов, словарей или объектов; у каждого из них есть некоторые идеи идеальной концепции. Однако, если у вас есть хотя бы базовое знакомство с любым современным и модным языком, таким как Scala, Groovy или Ruby, вы определенно почувствуете отсутствие функционального подхода в чистом AS3-способе обработки коллекций.
Язык коллекций
Что ж, давайте представим расширение языка Collections AS3, которое доступно в RASE Beta 10, сборка 8177+.
Полный словарь методов, дополненный примерами, доступен здесь: один для списков, а другой для карт (это изображения; прокрутите их вниз, они действительно ОГРОМНЫ).
Чтобы не потеряться в этих джунглях, давайте рассмотрим несколько простых вариантов использования. Первый пример из реальной жизни демонстрирует краткость кода коллекции:
Мы создаем list
, который может содержать только значения int
.
- Затем мы выбираем только те из них, которые удовлетворяют условию («
where
»). - Мы делаем что-то с каждым выбранным элементом («
select
»). - Мы конвертируем их в строки («
select
»). - Наконец, мы перебираем
list
и отслеживаем результат.
Where
, select
, select
selectMany
— эти операции просты в использовании при создании запроса.
Операции, подобные all
, any
, containsAll
и contains
отлично работают в условных выражениях (операторы « if
» и т. Д.).
Чтобы изменить список, у нас есть широкий спектр оружия: remove
, remove
, remove
, remove
removeWhere
, removeHead
removeTail
и т. Д.
Для тех, у кого определенно есть foldLeft
к извращению, мы подготовили несколько операций, таких как foldLeft
/ reduceLeft
, reduceLeft
/ reduceRight
, intersect
и т. Д.
Проще говоря, существует множество операций, подходящих для любой фантазии и почти для любой задачи. В некоторых операциях вы просто передаете ему одно или несколько значений, в других вы добавляете замыкание.
Списки и Карты
Язык коллекции преднамеренно прост. Он поддерживает два типа: List
и Map
. Map
очень похожа на тривиальный Dictionary
который содержит некоторые полезные методы — keys
, values
, containsKey
, containsValue
(полезно для проверок и условий), pushMap
(для объединения значений), removeKey
, removeValue
и т. Д.
Карты умные и надежные. Они не позволят вам добавить неверный ключ или значение:
Карты хорошо работают с любыми списками и запросами.
Существуют также операции преобразования, которые можно использовать, чтобы упростить встраивание новых расширений коллекций в ваш настоящий проект с чисто ActionScript. Просто возьмите тривиальный массив (или вектор) и примените операцию .toList
. После обработки списка (или карты) вы всегда можете преобразовать его обратно в стиль старой школы AS3, используя .toArray
или .toVector
.
Пример из реального мира
Чтобы продемонстрировать, как начать работу с этими коллекциями, вот пошаговое руководство, основанное на тривиальной ситуации. Предположим, ваша задача — создать список «предлагаемых пользователей» для учетной записи Twitter. Нам нужно обработать очень длинную коллекцию из сотен или тысяч объектов, извлечь короткий список (который соответствует ряду критериев) и применить некоторые операции к каждому элементу в этом коротком списке.
Мы не будем обращать внимание на взаимодействие с Twitter API, поскольку наша цель — показать, как начать работу с языком коллекций, и показать преимущества функционального подхода при работе с коллекциями в AS3.
Шаг 1: Создание проекта
Создайте новый проект с нуля и назовите его Collections. Если это ваш первый опыт работы с редактором, мы рекомендуем вам прочитать Руководство по Realaxy HelloWord и / или Обзор Realaxy для начинающих .
Шаг 2: Создание класса (начало)
Теперь нам нужно создать три класса для хранения структуры данных: User
, TwitterAccount
и Message
. Мы можем сделать это из меню Generate
, которое доступно через щелчок правой кнопкой мыши по коду или нажатие Ctrl + N.
Шаг 3: Создание класса (в процессе)
Введите имя класса во всплывающем окне.
Шаг 4: Создание класса (добавление полей)
Перейдите в положение <<Field>>
и нажмите Enter
.
Шаг 5: Создание класса (больше полей)
Добавьте следующие поля: username
, surname
и id
. Код будет выглядеть так:
Шаг 6: Добавление геттеров и сеттеров
Снова вызвать меню Ctrl + N.
Шаг 7: добавляем геттеры и сеттеры
Появится новое всплывающее окно. Выберите все вновь созданные поля и нажмите ОК .
Шаг 8: Добавление метода .toString()
Не забудьте добавить текстовую презентацию в класс User
. Добавьте метод .toString()
— элемент 5 из меню Ctrl-N (так же, как на скриншоте с шагами 2 и 6).
Шаг 9: Обзор кода
User
класс готов. Его код будет выглядеть так:
Шаг 10: TwitterAccount и классы сообщений
Используя тот же процесс, что и шаги 2-9, вы должны создать TwitterAccount
и Message
.
NB. Чтобы избежать ошибки типа (как показано на рисунке выше), вы должны импортировать язык Collections
из меню Ctrl + L :
NB2: TwitterAccount
и Message
должны быть сшиты. Чтобы это произошло, после импорта языка Collections
необходимо создать класс Message
, вернуться к классу TwitterAccount
и завершить строку, вызвавшую ошибку.
NB3: Не забудьте добавить методы получения, установки и метод .toString()
.
Шаг 11: Главный ()
Теперь пришло время написать некоторый код в Main()
. Во-первых, нам нужно добавить несколько полей.
NB. Используйте сочетание клавиш Smart Complete ( Ctrl-Shift-Space ), чтобы сэкономить немного времени при наборе следующих фраз:
Поскольку наш учебник представляет собой просто демонстрацию, которая показывает, как работать с коллекциями в AS3, мы пропустим часть, которая описывает, как получить эти данные из Twitter API.
Давайте просто представим, что у нас уже есть:
- список наших
followers
, - список пользователей,
followedBefore
- очень длинный список потенциальных кандидатов для следующих
candidatesLongList
—candidatesLongList
, - и, конечно же,
candidatesShortList
, который в данный момент пуст.
Третья коллекция может быть очень большой, содержащей сотни или даже тысячи предметов. Наша цель — применить сложный запрос и, таким образом, отрезать ненужные предметы по принципу Буонаротти: «Я видел ангела в мраморе и вырезал его, пока не освободил».
Шаг 12: Построение запроса
Перейдите к конструктору Main()
и введите в поле candidatesLongList
его метод « where
» (нажмите Ctrl-Space, чтобы использовать автозаполнение, как на скриншоте ниже):
Появится следующая фраза:
Не удивляйтесь, это просто Closure
, а « it
» — просто его параметр.
Закрытие (небольшое лирическое отступление)
Закрытие, по сути, та же анонимная функция, но с рядом небольших различий.
Во-первых, у Closure
очень лаконичный синтаксис. У параметров нет объявления типа (точнее, они есть, но такие объявления скрыты). Закрытие имеет специальное поведение — «последний оператор является возвращаемым значением & rdquo — что означает, что вы должны использовать« 1;
»(В последней строке) вместо« return 1;
»
Во-вторых, он имеет особое представление для однострочных замыканий — при таком замыкании точка с запятой на конце не указывается (по двум причинам: читаемость и краткость).
В отличие от анонимной функции (а также в качестве счетчика вышеупомянутых Arrays
и Vectors
) замыкание является безопасным по типу . Это означает, что автозаполнение и проверка типов будут работать в замыканиях.
В заключение, Closure
является своего рода функцией на стероидах. У этого есть много вкусных особенностей, которые помогают нам написать все быстро и кратко.
Шаг 13: Построение запроса
Вернемся к нашему незаконченному закрытию. Добавьте код, который будет реализовывать наши «правила». Этот код вернет урезанную версию candidatesLongList
которую не входит ни один из наших подписчиков:
Затем добавьте еще один критерий:
Теоретически, язык Коллекций позволяет вам вкладывать множество различных условий одно за другим. Давайте добавим еще один критерий (включая пользователей, которые имеют «Flash», «ActionScript» или «Adobe» в своем поле «Биография»), используя регулярное выражение :
Шаг 14: Получение результата
Выделите весь запрос и нажмите Ctrl-Alt-V . Новая переменная будет введена.
Теперь мы можем делать все, что хотим:
Затем мы скопировали бы содержимое result
в candidatesShortList
.
Шаг 15: Генерация чистого кода AS3
Создайте модуль с помощью Ctrl-F9 и посмотрите на окно вывода . Сгенерированный чистый AS3-код Main()
будет выглядеть так:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
|
package com.example{
import com.realaxy.actionScript.collections.util.CollectionsLanguageUtil;
import flash.display.Sprite;
public class Main extends Sprite {
private var followers : Array = new Array() ;
private var followedBefore : Array = new Array() ;
private var candidatesLongList : Array = new Array() ;
private var candidatesShortList : Array = new Array() ;
public function Main(){
//exclude our followers and users followed by us before
//include people with «Flash», «ActionScript» and «Adobe» in their bio
//add them all to the recommendations shortlist
this.candidatesShortList = CollectionsLanguageUtil.where(CollectionsLanguageUtil.where(candidatesLongList,
function ( n : TwitterAccount, stops : Object ) : Boolean {
return !CollectionsLanguageUtil.any(followers,
function ( f : TwitterAccount, stops : Object ) : Boolean {
return f.user.id != n.user.id ;
},
this, false) &&
!CollectionsLanguageUtil.any(followedBefore,
function ( f : TwitterAccount, stops : Object ) : Boolean {
return f.user.id != n.user.id ;
},
this, false);
},
this, false),
function ( it : TwitterAccount, stops : Object ) : Boolean {
return /Flash|ActionScript|Adobe/.test(it.bio) ;
},
this, false);
var names : Array = CollectionsLanguageUtil.select(candidatesShortList,
function ( it : TwitterAccount, stops : Object ) : String {
return it.user.username + «, » + it.user.surname ;
},
this, false);
CollectionsLanguageUtil.forEach(names,
function ( m : String, stops : Object ) : void {
//TODO: do something with ‘m’
},
this, false);
}
}
}
|
Кажется немного нечитаемым, а? Особенно по сравнению с нашим кодом DSL:
Вывод
Новое расширение языка Коллекции позволяет:
- улучшить код AS3, сделав его более лаконичным,
- сделать ваш код более понятным для человека, и
- облегчить превращение вашего последовательного кода в параллельный код.