Введение
Для работы со структурами данных в Dynamics AX
предусмотрены несколько классов коллекций, которые позволяют
хранить и извлекать не только данные, но и записи, и объекты.
Каждый класс имеет свои ограничения на хранимые типы
данных и доступ к ним, в таблице ниже они описаны:
Класс
|
Описание
|
Тип данных
|
Доступ
|
List
|
Значения
хранятся последовательно с возможностью добавления новых значений в начало
или конец списка.
|
Все значения
должны быть одного типа
|
Используется ListIterator или ListEnumerator
|
Set
|
Значения
хранятся неупорядоченно. Повторяющиеся значения не добавляются.
|
Все
значения должны быть одного типа
|
Используется SetIterator или SetEnumerator
|
Map
|
Значения имеют уникальный ключ.
|
Ключи
должны быть одного типа. Значения для каждого ключа также должны быть одного
типа.
|
Используется MapIterator или MapEnumerator
|
Array
|
Значения имеют
уникальный числовой ключ.
|
Все
значения должны быть одного типа
|
Доступ
осуществляется по числовому ключу.
|
Struct
|
Значения
имеют уникальный ключ строкового типа
|
Ключ
должен быть строковым. Значения могут быть любого типа.
|
Доступ
осуществляется по строковому ключу.
|
По сравнению с контейнерами, классы коллекций имеют
более функциональный интерфейс.
Все классы коллекций содержатся в
памяти, поэтому, при работе с ними, необходимо учитывать их размер. Если
необходимо обработать большой объем данных, то следует рассмотреть
альтернативные варианты, например, временные таблицы.
Рассмотрим сами классы ниже.
List (Список)
В
списке можно хранить данные одного типа в упорядоченной последовательности.
Элементы могут быть любого типа X++. Тип определяется при создании и не может
быть изменен после инициализации. Элементы могут добавляться в начало или конец
списка. Основные методы для работы со списками описаны в таблице ниже:
addEnd(_item)
|
Добавляет
элемент _item в конец
списка
|
addStart(_item)
|
Добавляет
элемент _item в начало
списка
|
appendList(_list)
|
Добавляет
элементы списка _list в конец текущего списка
|
elements
|
Возвращает
количество элементов в списке
|
getEnumerator
|
Возвращает
указатель
для извлечения элементов списка
|
В примере ниже создаются и объединяются 2 списка:
Результат:
Список можно инициализировать и через контейнер:
Результат:
Set (Множество)
Множества используются для хранения уникальных
значений, каждый элемент множества является ключом, по которому данные
автоматически сортируются при добавлении нового элемента – этим множества
отличаются от списков. Множества могут содержать любые типы X++.
При добавлении в множество элемента, который уже в нем
есть, ничего не произойдет - не будет никаких записей о том, сколько таких
вставок было. Например, если множество типа Integer (Types::Integer) содержит
только значение 7, то повторный вызов метода вставки еще одного значения 7 не
даст никакого эффекта. Не важно сколько таких вставок будет сделано, множество
так и будет содержать одно значение – 7.
Отсюда следуют 2 полезных варианта использования
множеств:
- хранение уникальных значений (например, RecId для избегания повторных действий над одной записью)
- сортировка потока произвольных значений
С множествами в X++ можно работать как с
математическими множествами, для этого есть операции, позволяющие получать
новые множества, используя 3 метода.
Наиболее полезные методы для работы с множествами
описаны в таблице ниже:
add(_item)
|
Добавляет
элемент _item в
множество
|
delete(_item)
|
Удаляет
выбранный элемент _item из множества
|
elements
|
Возвращает
количество элементов в множестве
|
getEnumerator
|
Возвращает
enumerator для
выборки из множества
|
in(_item)
|
Возвращает
true, если
элемент _item есть в
текущем множестве
|
difference(_set1,
_set2)
|
Возвращает
элементы, которые есть в множестве _set1, но которых нет в множестве _set2
|
intersection(_set1,
_set2)
|
Возвращает
новое множество, которое содержит элементы, содержащиеся в обоих множествах _set1 и _set2
|
union(_set1,
_set2)
|
Возвращает
новое множество, которое содержит элементы из обоих множеств _set1 и _set2.
|
В примере ниже демонстрируется сортировка при
заполнении множества:
Результат (нет повторяющихся значений и все элементы
упорядочены):
В примере ниже демонстрируется работа с множествами
X++ как с математическими множествами:
Результат:
Map (Карта соответствий)
Карта хранит пару ключ-значение. Для каждого ключа есть соответствующее
значение. Ключи уникальны и все одного типа. Значения тоже все одного типа, но
могут быть неуникальными. В качестве ключей и значений могут использоваться
любые типы, при этом типы ключей и значений в одной карте могут отличаться. По
картам быстро осуществляется поиск, что делает их полезными для кэширования
данных.
Несколько ключей могут относиться к
одному и тому же значению, но один ключ не может относиться к нескольким
значениям. При добавлении новой пары ключ-значение в карту, где уже есть такой
ключ с другим значением, связь меняется так, что ключ будет указывать на новое
значение (значение у старого ключа обновится).
Наиболее полезные методы для работы с множествами
описаны в таблице ниже:
delete(_key)
|
Удаляет
ключ _key (и,
соответственно, связанное значение) из карты
|
elements
|
Возвращает
количество пар ключ-элемент в карте
|
exists(_key)
|
Возвращает
true, если
ключ _key есть в карте
|
insert(_key,
_value)
|
Вставляет
пару ключ-значение, где ключ - _key, а значение - _value. Другими словами, поиски по ключу
_key
вернут значение _value. Если ключ _key уже есть в карте, то связанное с этим ключом значение обновится, так что новым значением для этого ключа станет _value.
|
lookup(_key)
|
Возвращает
значение, связанное с ключом _key.
|
Важно: вызов метода lookup для ключа, которого нет в карте выдаст ошибку. Таким образом, следует сначала вызывать метод exists для проверки существования ключа.
Класс
MapEnumerator используется для извлечений данных из карты. Для извлечения ключа
и значения из объекта MapEnumerator используются методы currentKey() и
currentValue().
Ниже пример работы с картами:
Результат:
Struct (Структура)
В структурах данные группируются в единое целое.
Использоваться могут все типы из Types.
Класс Struct – один из самых простых классов
коллекций. Использование структур похоже на использование контейнеров, которые
имеют небольшое количество записей на конкретных позициях. Основное
отличие от контейнеров в том, что структуры – это класс, а контейнеры –
встроенный в X++ тип данных. В структурах используются строковые индексы, в то
время как в контейнерах используются номерные индексы.
Основное преимущество структур – возможность
динамического добавления новых элементов, без необходимости создавать новый тип
в AOT.
Пример использования класса Struct:
Результат:
Array (Массив)
Объекты Array могут содержать элементы любого типа, в
отличие от встроенного типа данных «массив» в X++. Значения в Array хранятся
последовательно. Array можно расширить по необходимости, поэтому не нужно
определять его размер при создании объекта. Также как и у массивов в X++
нумерация в Array начинается с единицы, а не нуля.
Пример использования Array:
Результат:
Помимо описанных классов есть еще пара не самых популярных: Stack и StackBase.
Stack (Стек)
В стеке способ организации данных построен по принципу LIFO (last in first
out, последним пришел - первым ушел). Элемент добавляется вызовом метода push,
а удаляется методом pop. Класс Stack в Dynamics AX может хранить только экземпляры
контейнеров, соответственно, данные в стеке могут быть такого же типа, как и в
контейнерах.
Пример использования стека:
Результат:
StackBase (Базовый стек)
У класса StackBase, в отличие от Stack, нет ограничения
на хранение только экземпляров контейнеров. Класс StackBase предоставляет ту же
функциональность, как и Stack с возможностью хранить данные любого типа,
включая объекты.
Пример использования StackBase:
Результат:
На этом, пожалуй, описание классов коллекций завершу.
Happy DAXing!
Комментариев нет:
Отправить комментарий