Статьи

Запрос (и завоевание) больших коллекций в AS3 с помощью Realaxy Editor

Хорошие новости, все. Все, кто работает с массивами и векторами, а значит, и все разработчики, получат новые возможности: начиная с сборки Flash в конце августа 2011 года, Realaxy ActionScript Editor (RASE) поддерживает новое расширение языка Collections AS3. В этом посте мы покажем вам, на что он способен.

Логотип Realaxy

Коллекция — это общий термин, который примерно означает «группа объектов одинакового типа, сгруппированных вместе». Сборка коллекции в ActionScript 3.0 может быть выполнена с использованием массивов, векторов, словарей или объектов; у каждого из них есть некоторые идеи идеальной концепции. Однако, если у вас есть хотя бы базовое знакомство с любым современным и модным языком, таким как Scala, Groovy или Ruby, вы определенно почувствуете отсутствие функционального подхода в чистом AS3-способе обработки коллекций.


Что ж, давайте представим расширение языка Collections AS3, которое доступно в RASE Beta 10, сборка 8177+.

Полный словарь методов, дополненный примерами, доступен здесь: один для списков, а другой для карт (это изображения; прокрутите их вниз, они действительно ОГРОМНЫ).

Чтобы не потеряться в этих джунглях, давайте рассмотрим несколько простых вариантов использования. Первый пример из реальной жизни демонстрирует краткость кода коллекции:

Мы создаем list , который может содержать только значения int .

  1. Затем мы выбираем только те из них, которые удовлетворяют условию (« where »).
  2. Мы делаем что-то с каждым выбранным элементом (« select »).
  3. Мы конвертируем их в строки (« select »).
  4. Наконец, мы перебираем 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.


Создайте новый проект с нуля и назовите его Collections. Если это ваш первый опыт работы с редактором, мы рекомендуем вам прочитать Руководство по Realaxy HelloWord и / или Обзор Realaxy для начинающих .


Теперь нам нужно создать три класса для хранения структуры данных: User , TwitterAccount и Message . Мы можем сделать это из меню Generate , которое доступно через щелчок правой кнопкой мыши по коду или нажатие Ctrl + N.


Введите имя класса во всплывающем окне.


Перейдите в положение <<Field>> и нажмите Enter .


Добавьте следующие поля: username , surname и id . Код будет выглядеть так:


Снова вызвать меню Ctrl + N.


Появится новое всплывающее окно. Выберите все вновь созданные поля и нажмите ОК .


Не забудьте добавить текстовую презентацию в класс User . Добавьте метод .toString() — элемент 5 из меню Ctrl-N (так же, как на скриншоте с шагами 2 и 6).


User класс готов. Его код будет выглядеть так:


Используя тот же процесс, что и шаги 2-9, вы должны создать TwitterAccount и Message .

NB. Чтобы избежать ошибки типа (как показано на рисунке выше), вы должны импортировать язык Collections из меню Ctrl + L :

NB2: TwitterAccount и Message должны быть сшиты. Чтобы это произошло, после импорта языка Collections необходимо создать класс Message , вернуться к классу TwitterAccount и завершить строку, вызвавшую ошибку.

NB3: Не забудьте добавить методы получения, установки и метод .toString() .


Теперь пришло время написать некоторый код в Main() . Во-первых, нам нужно добавить несколько полей.

NB. Используйте сочетание клавиш Smart Complete ( Ctrl-Shift-Space ), чтобы сэкономить немного времени при наборе следующих фраз:

Поскольку наш учебник представляет собой просто демонстрацию, которая показывает, как работать с коллекциями в AS3, мы пропустим часть, которая описывает, как получить эти данные из Twitter API.

Давайте просто представим, что у нас уже есть:

  1. список наших followers ,
  2. список пользователей, followedBefore
  3. очень длинный список потенциальных кандидатов для следующих candidatesLongListcandidatesLongList ,
  4. и, конечно же, candidatesShortList , который в данный момент пуст.

Третья коллекция может быть очень большой, содержащей сотни или даже тысячи предметов. Наша цель — применить сложный запрос и, таким образом, отрезать ненужные предметы по принципу Буонаротти: «Я видел ангела в мраморе и вырезал его, пока не освободил».


Перейдите к конструктору Main() и введите в поле candidatesLongList его метод « where » (нажмите Ctrl-Space, чтобы использовать автозаполнение, как на скриншоте ниже):

Появится следующая фраза:

Не удивляйтесь, это просто Closure , а « it » — просто его параметр.


Закрытие, по сути, та же анонимная функция, но с рядом небольших различий.

Во-первых, у Closure очень лаконичный синтаксис. У параметров нет объявления типа (точнее, они есть, но такие объявления скрыты). Закрытие имеет специальное поведение — «последний оператор является возвращаемым значением & rdquo — что означает, что вы должны использовать« 1; »(В последней строке) вместо« return 1; »

Во-вторых, он имеет особое представление для однострочных замыканий — при таком замыкании точка с запятой на конце не указывается (по двум причинам: читаемость и краткость).

В отличие от анонимной функции (а также в качестве счетчика вышеупомянутых Arrays и Vectors ) замыкание является безопасным по типу . Это означает, что автозаполнение и проверка типов будут работать в замыканиях.

В заключение, Closure является своего рода функцией на стероидах. У этого есть много вкусных особенностей, которые помогают нам написать все быстро и кратко.


Вернемся к нашему незаконченному закрытию. Добавьте код, который будет реализовывать наши «правила». Этот код вернет урезанную версию candidatesLongList которую не входит ни один из наших подписчиков:

Затем добавьте еще один критерий:

Теоретически, язык Коллекций позволяет вам вкладывать множество различных условий одно за другим. Давайте добавим еще один критерий (включая пользователей, которые имеют «Flash», «ActionScript» или «Adobe» в своем поле «Биография»), используя регулярное выражение :


Выделите весь запрос и нажмите Ctrl-Alt-V . Новая переменная будет введена.

Теперь мы можем делать все, что хотим:

Затем мы скопировали бы содержимое result в candidatesShortList .


Создайте модуль с помощью 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, сделав его более лаконичным,
  • сделать ваш код более понятным для человека, и
  • облегчить превращение вашего последовательного кода в параллельный код.