Массивы в Ninox
Простые массивы
Работать с массивами текстов или чисел просто:
var myArray := ["a", "b", "d"];
index(myArray, "b");
myArray := array(myArray, ["c"]);
myArray order this;
Сортировать можно также с помощью order, sort и unsort — для текстовых и числовых массивов.
Другие функции для работы с массивами описаны в документации Ninox.
Двумерные массивы
Ninox не поддерживает двумерные массивы напрямую. Вместо них используйте массив объектов JSON.
Например, отсортируем массив по второму элементу поля d2:
var myArray := [{'d2':["a", "Z"]}, {'d2':["b", "B"]}, {'d2':["c", "C"]}, {'d2':["d", "D"]}];
(myArray order by item('d2', 1));
Этот код возвращает: [{"d2":["b","B"]},{"d2":["c","C"]},{"d2":["d","D"]},{"d2":["a","Z"]}]
Фильтрация массивов
Массивы фильтруются так же, как результат select. Для текстовых и числовых массивов используйте this, чтобы обратиться к фильтруемому значению:
var myArray := ["Jan", "Fred", "Jacques"];
myArray[this like "J"] order this;
Для массивов JSON обращайтесь прямо к ключу:
var myArray := [
{ 'prénom' : "Jan", nom : "Augustin" },
{ 'prénom' : "Fred", nom : "Baillot" },
{ 'prénom' : "Jacques", nom : "Tur" }
];
myArray[nom like "i"] order 'prénom';
Этот код возвращает массив JSON: [{"prénom":"Fred","nom":"Baillot"}, {"prénom":"Jan","nom":"Augustin"}]
Собственные действия над массивами JSON
Для массивов JSON можно добавить блок кода (в скобках), выполняемый на каждом витке. Как и в for in, тип получаемого массива определяется последней строкой блока.
Пример: вычислим длину полных имён (prénom + nom):
var myArray := [
{ 'prénom' : "Leo", nom : "Martin" },
{ 'prénom' : "Paul", nom : "Garnet" },
{ 'prénom' : "Pierre", nom : "Dur" }
];
var nameLengths := myArray[nom like "a"].(
var fullName := ---{'prénom'} {nom}---;
length(fullName)
);
nameLengths;
Этот код возвращает массив чисел [10, 11] — длины полных имён.
Создание пустого типизированного массива
В Ninox обычный приём для создания пустого массива, сохраняющего нужный тип записей, — выполнить select с фильтром where false.
Запрос не возвращает ни одной записи, но сохраняет тип элементов массива.
"Empty Invoice Item array:";
let t := (select 'Invoice Item' where false);
- Теперь
t— это массив, элементы которого имеют тип Invoice Item. - Поскольку он пуст, но типизирован, его можно смело брать за отправную точку для операций
array().
Почему не просто []?
Литерал [] — это нетипизированный массив. Часто он работает, но в сочетании с array() над наборами записей Ninox может пожаловаться на несовпадение типов.
Приём select … where false полностью снимает эту проблему.
Создание пустого массива для простых типов (число, текст, JSON…)
Когда нужен пустой массив скалярных значений — чисел, строк или объектов JSON, — нет таблицы, из которой можно было бы сделать select.
Но типизированный пустой массив всё равно можно получить: создайте [] с одним фиктивным элементом и тут же отфильтруйте его:
"Empty number / text / JSON array:";
let t := [1][false]; "t is now an empty but number typed array";
[1] даёт числовой массив из одного элемента; фильтр [false] убирает этот элемент, оставляя пустой массив, сохранивший тип число.
Если нужны другие типы, поставьте вместо 1 текстовый литерал или литерал JSON.
Развёртывание двумерного массива
Каждый Invoice содержит собственный подмассив Invoice Items. Чтобы получить один общий список со всеми позициями всех счетов, переберите счета и соедините их подмассивы.
"Initialize empty array:";
let t := (select 'Invoice Item' where false);
"Iterate over each invoice and add its items:";
for i in Invoices do
t := array(t, i.'Invoice Items')
end;
"Return the flattened list:";
t
Как это работает
for i in Invoices do … endперебирает все записи Invoice.array(t, i.'Invoice Items')соединяет текущее значениеtс массивом позиций этого счёта.- На первом витке добавляются позиции первого счёта.
- На втором — позиции второго счёта, и так далее.
- По окончании цикла
tсодержит все позиции всех счетов в одном плоском массиве.
Теперь можно, например, вызвать count(t), чтобы узнать общее число позиций, или напрямую перебирать и фильтровать t.
