//////////////////////////////////////////////////////////////////////////////// // Модуль: A1sAR // Назначение: // Утилиты для работы с массивами: создание, объединение, фильтрация, сортировка. // // Автор: A1sCode (a1scode.ru) // Версия: 2.1 // Дата: 2026-01-20 //////////////////////////////////////////////////////////////////////////////// #Область ФабрикиМассивов // // Создаёт массив из переданных значений (до 40 элементов). ✦ // Значения для добавления в массив ➤ // Удалить дубликаты из результата ➤ // Array — новый массив с переданными значениями ⬅ // // // // Базовое использование // Числа = A1sAR.Of(1, 2, 3); // [1, 2, 3] // // // С Неопределено — РАБОТАЕТ! // Смешанный = A1sAR.Of(1, Неопределено, 3); // [1, Неопределено, 3] // // Функция Of( Знач1 = "__A1S_∅__", Знач2 = "__A1S_∅__", Знач3 = "__A1S_∅__", Знач4 = "__A1S_∅__", Знач5 = "__A1S_∅__", Знач6 = "__A1S_∅__", Знач7 = "__A1S_∅__", Знач8 = "__A1S_∅__", Знач9 = "__A1S_∅__", Знач10 = "__A1S_∅__", Знач11 = "__A1S_∅__", Знач12 = "__A1S_∅__", Знач13 = "__A1S_∅__", Знач14 = "__A1S_∅__", Знач15 = "__A1S_∅__", Знач16 = "__A1S_∅__", Знач17 = "__A1S_∅__", Знач18 = "__A1S_∅__", Знач19 = "__A1S_∅__", Знач20 = "__A1S_∅__", Знач21 = "__A1S_∅__", Знач22 = "__A1S_∅__", Знач23 = "__A1S_∅__", Знач24 = "__A1S_∅__", Знач25 = "__A1S_∅__", Знач26 = "__A1S_∅__", Знач27 = "__A1S_∅__", Знач28 = "__A1S_∅__", Знач29 = "__A1S_∅__", Знач30 = "__A1S_∅__", Знач31 = "__A1S_∅__", Знач32 = "__A1S_∅__", Знач33 = "__A1S_∅__", Знач34 = "__A1S_∅__", Знач35 = "__A1S_∅__", Знач36 = "__A1S_∅__", Знач37 = "__A1S_∅__", Знач38 = "__A1S_∅__", Знач39 = "__A1S_∅__", Знач40 = "__A1S_∅__", ТолькоУникальные = Ложь ) Экспорт //ib = "Создание массива из переданных значений"; //✍ ø = "__A1S_∅__"; //✏ локальный маркер пустоты Массив = Новый Массив; //✏ Если Знач1 <> ø Тогда Массив.Добавить(Знач1); КонецЕсли; //⚡ Если Знач2 <> ø Тогда Массив.Добавить(Знач2); КонецЕсли; //⚡ Если Знач3 <> ø Тогда Массив.Добавить(Знач3); КонецЕсли; //⚡ Если Знач4 <> ø Тогда Массив.Добавить(Знач4); КонецЕсли; //⚡ Если Знач5 <> ø Тогда Массив.Добавить(Знач5); КонецЕсли; //⚡ Если Знач6 <> ø Тогда Массив.Добавить(Знач6); КонецЕсли; //⚡ Если Знач7 <> ø Тогда Массив.Добавить(Знач7); КонецЕсли; //⚡ Если Знач8 <> ø Тогда Массив.Добавить(Знач8); КонецЕсли; //⚡ Если Знач9 <> ø Тогда Массив.Добавить(Знач9); КонецЕсли; //⚡ Если Знач10 <> ø Тогда Массив.Добавить(Знач10); КонецЕсли; //⚡ Если Знач11 <> ø Тогда Массив.Добавить(Знач11); КонецЕсли; //⚡ Если Знач12 <> ø Тогда Массив.Добавить(Знач12); КонецЕсли; //⚡ Если Знач13 <> ø Тогда Массив.Добавить(Знач13); КонецЕсли; //⚡ Если Знач14 <> ø Тогда Массив.Добавить(Знач14); КонецЕсли; //⚡ Если Знач15 <> ø Тогда Массив.Добавить(Знач15); КонецЕсли; //⚡ Если Знач16 <> ø Тогда Массив.Добавить(Знач16); КонецЕсли; //⚡ Если Знач17 <> ø Тогда Массив.Добавить(Знач17); КонецЕсли; //⚡ Если Знач18 <> ø Тогда Массив.Добавить(Знач18); КонецЕсли; //⚡ Если Знач19 <> ø Тогда Массив.Добавить(Знач19); КонецЕсли; //⚡ Если Знач20 <> ø Тогда Массив.Добавить(Знач20); КонецЕсли; //⚡ Если Знач21 <> ø Тогда Массив.Добавить(Знач21); КонецЕсли; //⚡ Если Знач22 <> ø Тогда Массив.Добавить(Знач22); КонецЕсли; //⚡ Если Знач23 <> ø Тогда Массив.Добавить(Знач23); КонецЕсли; //⚡ Если Знач24 <> ø Тогда Массив.Добавить(Знач24); КонецЕсли; //⚡ Если Знач25 <> ø Тогда Массив.Добавить(Знач25); КонецЕсли; //⚡ Если Знач26 <> ø Тогда Массив.Добавить(Знач26); КонецЕсли; //⚡ Если Знач27 <> ø Тогда Массив.Добавить(Знач27); КонецЕсли; //⚡ Если Знач28 <> ø Тогда Массив.Добавить(Знач28); КонецЕсли; //⚡ Если Знач29 <> ø Тогда Массив.Добавить(Знач29); КонецЕсли; //⚡ Если Знач30 <> ø Тогда Массив.Добавить(Знач30); КонецЕсли; //⚡ Если Знач31 <> ø Тогда Массив.Добавить(Знач31); КонецЕсли; //⚡ Если Знач32 <> ø Тогда Массив.Добавить(Знач32); КонецЕсли; //⚡ Если Знач33 <> ø Тогда Массив.Добавить(Знач33); КонецЕсли; //⚡ Если Знач34 <> ø Тогда Массив.Добавить(Знач34); КонецЕсли; //⚡ Если Знач35 <> ø Тогда Массив.Добавить(Знач35); КонецЕсли; //⚡ Если Знач36 <> ø Тогда Массив.Добавить(Знач36); КонецЕсли; //⚡ Если Знач37 <> ø Тогда Массив.Добавить(Знач37); КонецЕсли; //⚡ Если Знач38 <> ø Тогда Массив.Добавить(Знач38); КонецЕсли; //⚡ Если Знач39 <> ø Тогда Массив.Добавить(Знач39); КонецЕсли; //⚡ Если Знач40 <> ø Тогда Массив.Добавить(Знач40); КонецЕсли; //⚡ Если ТолькоУникальные Тогда //⚡ Массив = RemoveDuplicates(Массив); //▶️ КонецЕсли; Возврат Массив; //↩ КонецФункции // A1sAR.OfFixed(P1, P2, ..., P40) // Creates fixed (immutable) array from values. // @return FixedArray // // Example: // Const = A1sAR.OfFixed("A", "B", "C"); // // Const[0] = "X"; // Ошибка! Массив фиксирован // &AtServer Function OfFixed( P1 = "__A1S_∅__", P2 = "__A1S_∅__", P3 = "__A1S_∅__", P4 = "__A1S_∅__", P5 = "__A1S_∅__", P6 = "__A1S_∅__", P7 = "__A1S_∅__", P8 = "__A1S_∅__", P9 = "__A1S_∅__", P10 = "__A1S_∅__", P11 = "__A1S_∅__", P12 = "__A1S_∅__", P13 = "__A1S_∅__", P14 = "__A1S_∅__", P15 = "__A1S_∅__", P16 = "__A1S_∅__", P17 = "__A1S_∅__", P18 = "__A1S_∅__", P19 = "__A1S_∅__", P20 = "__A1S_∅__", P21 = "__A1S_∅__", P22 = "__A1S_∅__", P23 = "__A1S_∅__", P24 = "__A1S_∅__", P25 = "__A1S_∅__", P26 = "__A1S_∅__", P27 = "__A1S_∅__", P28 = "__A1S_∅__", P29 = "__A1S_∅__", P30 = "__A1S_∅__", P31 = "__A1S_∅__", P32 = "__A1S_∅__", P33 = "__A1S_∅__", P34 = "__A1S_∅__", P35 = "__A1S_∅__", P36 = "__A1S_∅__", P37 = "__A1S_∅__", P38 = "__A1S_∅__", P39 = "__A1S_∅__", P40 = "__A1S_∅__" ) Export Return New FixedArray(Of( P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, P36, P37, P38, P39, P40 )); EndFunction // // Создает новый массив заданного размера, заполненный одинаковым значением. ✦ // Размер массива ➤ // Значение для заполнения всех элементов ➤ // Array — новый массив заполненный значениями ⬅ // // // // A1sAR.OfN(5, "test") -> ["test", "test", "test", "test", "test"] // // A1sAR.OfN(3, 0) -> [0, 0, 0] // // A1sAR.OfN(2, Новый Структура()) -> [Структура{}, Структура{}] // // Функция OfN(ArraySize, DefaultValueForAllElements) Экспорт //⚙ ib = "Создание массива размером " + Строка(ArraySize); //✍ Если ТипЗнч(ArraySize) <> Тип("Число") ИЛИ ArraySize < 0 Тогда //⚡ Возврат Новый Массив(); //↩ КонецЕсли; ResultArray = Новый Массив(); //✏ Для i = 0 По ArraySize - 1 Цикл //⟳ ResultArray.Добавить(DefaultValueForAllElements); //✏ КонецЦикла; Возврат ResultArray; //↩ КонецФункции // // Заполняет существующий массив одинаковым значением. ✦ // Существующий массив для заполнения ➤ // Значение для заполнения ➤ // Boolean — успешно ли выполнена операция ⬅ // // // // arr = Новый Массив(); // // arr.Добавить(1); arr.Добавить(2); arr.Добавить(3); // // A1sAR.Fill(arr, "new") -> arr станет ["new", "new", "new"] // // Функция Fill(ExistingArray, DefaultValueForAllElements) Экспорт //⚙ ib = "Заполнение существующего массива"; //✍ Если ТипЗнч(ExistingArray) <> Тип("Массив") Тогда //⚡ Возврат Ложь; //↩ КонецЕсли; ArraySize = ExistingArray.Количество(); //✏ Для i = 0 По ArraySize - 1 Цикл //⟳ ExistingArray[i] = DefaultValueForAllElements; //✏ КонецЦикла; Возврат Истина; //↩ КонецФункции // A1sAR.ToFixed(Array) // Converts regular array to fixed array. // @param Array - source array // @return FixedArray // &AtServer Function ToFixed(Array) Export If TypeOf(Array) <> Type("Array") Then Return Undefined; EndIf; Return New FixedArray(Array); EndFunction #КонецОбласти #Область СтруктурированиеМассива /// ✦ Chunk — Разбивает массив на массивы указанного размера /// ➤ Array (Массив) — Исходный массив /// ➤ Size (Число) — Размер чанка (количество элементов в каждом подмассиве) /// ⬅ Массив — Массив массивов /// /// Примеры: /// Группы = A1sAR.Chunk([1, 2, 3, 4, 5], 2); // [[1, 2], [3, 4], [5]] /// Функция Chunk(Array, Size) Экспорт ib = "Разбивает массив на части указанного размера"; //✍ Результат = Новый Массив; //✏ ТекущийЧанк = Новый Массив; //✏ Счетчик = 0; //✏ Если Size <= 0 Тогда // Защита от деления на 0 или отрицательных значений Возврат Результат; КонецЕсли; Для Каждого Элемент Из Array Цикл //⟳ ТекущийЧанк.Добавить(Элемент); //✏ Счетчик = Счетчик + 1; //✏ Если Счетчик = Size Тогда //⚡ Результат.Добавить(ТекущийЧанк); //✏ ТекущийЧанк = Новый Массив; //✏ Счетчик = 0; //✏ КонецЕсли; КонецЦикла; // Добавляем остаток, если он есть Если ТекущийЧанк.Количество() > 0 Тогда //⚡ Результат.Добавить(ТекущийЧанк); //✏ КонецЕсли; Возврат Результат; //↩ КонецФункции /// ✦ Flatten — Выравнивает массив на один уровень вложенности /// ➤ Array (Массив) — Исходный массив (может содержать подмассивы) /// ⬅ Массив — Новый массив с элементами верхнего уровня /// /// Примеры: /// Плоский = A1sAR.Flatten([ [1, 2], [3, 4], [5] ]); // [1, 2, 3, 4, 5] /// Смеш = A1sAR.Flatten([ 1, [2, [3, 4]], 5 ]); // [1, 2, [3, 4], 5] (только 1 уровень!) /// Функция Flatten(Array) Экспорт ib = "Сливает подмассивы в один основной массив (на 1 уровень глубины)"; //✍ Результат = Новый Массив; //✏ Для Каждого Элемент Из Array Цикл //⟳ Если ТипЗнч(Элемент) = Тип("Массив") Тогда //⚡ // Распаковываем элементы подмассива Для Каждого ВложенныйЭлемент Из Элемент Цикл //⟳ Результат.Добавить(ВложенныйЭлемент); //✏ КонецЦикла; Иначе Результат.Добавить(Элемент); //✏ КонецЕсли; КонецЦикла; Возврат Результат; //↩ КонецФункции /// Вставляет элемент в массив по указанному индексу (неизменяемый метод). /// ➤ Массив (Массив) — Исходный массив /// ➤ Индекс (Число) — Позиция вставки /// ➤ Значение (Произвольный) — Вставляемое значение /// ⬅ Массив — Новый массив с вставленным элементом Функция Insert(Массив, Индекс, Значение) Экспорт // Защита от отрицательного индекса (устанавливаем в начало) Если Индекс < 0 Тогда Индекс = 0; КонецЕсли; // Если индекс за пределами, копируем и добавляем в конец // Используем конструктор с ФиксированнымМассивом для максимальной скорости копирования Результат = Новый Массив(Новый ФиксированныйМассив(Массив)); Если Индекс > Результат.Количество() Тогда Индекс = Результат.Количество(); КонецЕсли; Результат.Вставить(Индекс, Значение); Возврат Результат; КонецФункции /// Удаляет элемент из массива по указанному индексу (неизменяемый метод). /// ➤ Массив (Массив) — Исходный массив /// ➤ Индекс (Число) — Позиция для удаления /// ⬅ Массив — Новый массив без удаленного элемента (или исходный, если индекс неверный) Функция RemoveAt(Массив, Индекс) Экспорт // ✅ ОПТИМИЗАЦИЯ: Если индекс некорректный, просто возвращаем исходный массив. // Это решает проблему теста (сравнение ссылок Res13 = Arr13 станет Истиной) // и экономит память/время на ненужное копирование. Если Индекс < 0 Или Индекс >= Массив.Количество() Тогда Возврат Массив; КонецЕсли; // Создаем копию только если удаление реально произойдет Результат = Новый Массив(Новый ФиксированныйМассив(Массив)); Результат.Удалить(Индекс); Возврат Результат; КонецФункции /// ✦ Split — Разделить массив на два по значению /// ➤ Array (Массив) — Исходный массив /// ➤ Value (Произвольный) — Значение-разделитель /// ➤ IncludeSeparator (Булево) — Включить разделитель во вторую часть (по умолчанию Ложь) /// ⬅ Структура — {Before: Массив, After: Массив} /// /// Примеры: /// Части = A1sAR.Split(A1sAR.Of(1, 2, 3, 4, 5), 3); /// // Части.Before = [1, 2] /// // Части.After = [4, 5] /// Функция Split(Array, Value, IncludeSeparator = Ложь) Экспорт ib = "Разделяет массив на две части по значению-разделителю"; Before = Новый Массив; //✏ After = Новый Массив; //✏ Найден = Ложь; //✏ Для Каждого Элемент Из Array Цикл //⟳ Если НЕ Найден И Элемент = Value Тогда //⚡ Найден = Истина; Если IncludeSeparator Тогда //⚡ After.Добавить(Элемент); КонецЕсли; ИначеЕсли Найден Тогда //⚡ After.Добавить(Элемент); Иначе Before.Добавить(Элемент); КонецЕсли; КонецЦикла; Возврат Новый Структура("Before,After", Before, After); //↩ КонецФункции /// ✦ SplitAt — Разделить массив по индексу /// ➤ Array (Массив) — Исходный массив /// ➤ Index (Число) — Индекс разделения (элемент с этим индексом попадёт во вторую часть) /// ⬅ Структура — {Before: Массив, After: Массив} /// /// Примеры: /// Части = A1sAR.SplitAt(A1sAR.Of(1, 2, 3, 4, 5), 2); /// // Части.Before = [1, 2] /// // Части.After = [3, 4, 5] /// Функция SplitAt(Array, Index) Экспорт ib = "Разделяет массив на две части по индексу"; Before = Новый Массив; //✏ After = Новый Массив; //✏ Для i = 0 По Array.Количество() - 1 Цикл //⟳ Если i < Index Тогда //⚡ Before.Добавить(Array[i]); Иначе After.Добавить(Array[i]); КонецЕсли; КонецЦикла; Возврат Новый Структура("Before,After", Before, After); //↩ КонецФункции /// Создает копию массива с отсортированными по возрастанию элементами Функция Sort(Массив) Экспорт Список = Новый СписокЗначений; Для Каждого Элемент Из Массив Цикл Список.Добавить(Элемент); КонецЦикла; Список.СортироватьПоЗначению(); Результат = Новый Массив; Для Счет = 0 По Список.Количество() - 1 Цикл //Результат.Добавить(Список.Получить(Счет)); Результат.Добавить(Список.Получить(Счет).Значение); КонецЦикла; Возврат Результат; КонецФункции /// Создает копию массива с элементами в обратном порядке Функция Reverse(Массив) Экспорт Результат = Новый Массив; Индекс = Массив.Количество() - 1; Пока Индекс >= 0 Цикл Результат.Добавить(Массив[Индекс]); Индекс = Индекс - 1; КонецЦикла; Возврат Результат; КонецФункции // // // Глубоко сбрасывает значения элементов массива, // заменяя их значениями по умолчанию в соответствии с типами. // Поддерживает вложенные массивы, структуры и соответствия. // ✦ // Исходный массив ➤ // Array — новый массив со сброшенными значениями ⬅ // // Функция ResetDeep(SourceArray) Экспорт Если ТипЗнч(SourceArray) <> Тип("Массив") Тогда Возврат Новый Массив; КонецЕсли; Возврат ResetDeepValue(SourceArray); КонецФункции // ===== ВНУТРЕННЯЯ РЕКУРСИЯ ===== // // // Внутренняя рекурсивная функция. // Сбрасывает значение к значению по умолчанию в соответствии с типом. // Используется функцией ResetDeep. // ✦ // // Значение любого поддерживаемого типа // (Массив, Структура, Соответствие, примитивы). // ➤ // // Arbitrary — значение по умолчанию для данного типа, // либо структура той же формы со сброшенными значениями. // ⬅ // // Функция ResetDeepValue(Значение) Если Значение = Неопределено Тогда Возврат Неопределено; КонецЕсли; ТипЗначения = ТипЗнч(Значение); // Массив Если ТипЗначения = Тип("Массив") Тогда Результат = Новый Массив; Для Каждого Элемент Из Значение Цикл Результат.Добавить(ResetDeepValue(Элемент)); КонецЦикла; Возврат Результат; КонецЕсли; // Структура Если ТипЗначения = Тип("Структура") Тогда Результат = Новый Структура; Для Каждого КлючИЗначение Из Значение Цикл Результат.Вставить( КлючИЗначение.Ключ, ResetDeepValue(КлючИЗначение.Значение) ); КонецЦикла; Возврат Результат; КонецЕсли; // Соответствие Если ТипЗначения = Тип("Соответствие") Тогда Результат = Новый Соответствие; Для Каждого Ключ Из Значение Цикл СтароеЗначение = Значение[Ключ]; НовоеЗначение = ResetDeepValue(СтароеЗначение); Результат.Вставить(Ключ, НовоеЗначение); КонецЦикла; Возврат Результат; КонецЕсли; // Примитивы — сброс по типу Попытка Типы = Новый Массив; Типы.Добавить(ТипЗначения); ОписаниеТипа = Новый ОписаниеТипов(Типы); Возврат ОписаниеТипа.ПривестиЗначение(); Исключение // Тихая ошибка — тип не поддерживает ПривестиЗначение() Возврат Неопределено; КонецПопытки; КонецФункции // // Сбрасывает значения всех элементов массива к значениям по умолчанию для их типов. ✦ // Массив для обработки (изменяется "на месте") ➤ // Boolean — Истина, если операция выполнена успешно ⬅ // // // // Пример 1: Простые типы // Arr = A1sAR.Of(100, "Текст", Истина); // A1sAR.Reset(Arr); // // Arr = [0, "", Ложь] // // // Пример 2: Составные типы (Ваша фишка!) // RowData = Новый Структура("Код, Наименование", 1, "Яблоко"); // Arr2 = A1sAR.Of(RowData, Новый Массив); // // A1sAR.Reset(Arr2); // // Arr2 = [НоваяСтруктура{}, НовыйМассив{}] // // Структура и Массив пересозданы "с нуля", старые данные удалены. // // // Использует метод Тип.ПривестиЗначение() для получения значения по умолчанию. // Это работает для примитивов, а также для Массивов и Структур (создает пустые экземпляры). // // Функция Reset(SourceArray) Экспорт //⚙ ib = "Сброс массива к значениям по умолчанию"; //✍ Если ТипЗнч(SourceArray) <> Тип("Массив") Тогда //⚡ Возврат Ложь; //↩ КонецЕсли; Результат = Новый Массив; //↩ Для Каждого Элемент Из SourceArray Цикл Если Элемент = Неопределено Тогда Результат.Добавить(Неопределено); Продолжить; КонецЕсли; ТипЭлемента = ТипЗнч(Элемент); Типы = Новый Массив; Типы.Добавить(ТипЭлемента); ОписаниеТипа = Новый ОписаниеТипов(Типы); Попытка Результат.Добавить(ОписаниеТипа.ПривестиЗначение()); Исключение Результат.Добавить(Неопределено); КонецПопытки; КонецЦикла; Возврат Результат; //↩ КонецФункции #КонецОбласти #Область Множества /// Объединяет до 8 массивов в один /// Первый массив /// Второй массив /// Третий массив /// Четвертый массив /// Пятый массив /// Шестой массив /// Седьмой массив /// Восьмой массив /// Удалить дубликаты из результата /// Объединенный массив Функция Concatenate(Массив1, Массив2 = Неопределено, Массив3 = Неопределено, Массив4 = Неопределено, Массив5 = Неопределено, Массив6 = Неопределено, Массив7 = Неопределено, Массив8 = Неопределено, ТолькоУникальные = Ложь) Экспорт Результат = Новый Массив; // Создаем массив всех переданных массивов для итерации МассивыДляОбъединения = Новый Массив; Если Массив1 <> Неопределено Тогда МассивыДляОбъединения.Добавить(Массив1); КонецЕсли; Если Массив2 <> Неопределено Тогда МассивыДляОбъединения.Добавить(Массив2); КонецЕсли; Если Массив3 <> Неопределено Тогда МассивыДляОбъединения.Добавить(Массив3); КонецЕсли; Если Массив4 <> Неопределено Тогда МассивыДляОбъединения.Добавить(Массив4); КонецЕсли; Если Массив5 <> Неопределено Тогда МассивыДляОбъединения.Добавить(Массив5); КонецЕсли; Если Массив6 <> Неопределено Тогда МассивыДляОбъединения.Добавить(Массив6); КонецЕсли; Если Массив7 <> Неопределено Тогда МассивыДляОбъединения.Добавить(Массив7); КонецЕсли; Если Массив8 <> Неопределено Тогда МассивыДляОбъединения.Добавить(Массив8); КонецЕсли; // Объединяем все массивы Для Каждого ТекущийМассив Из МассивыДляОбъединения Цикл Для Каждого Элемент Из ТекущийМассив Цикл Результат.Добавить(Элемент); КонецЦикла; КонецЦикла; // При необходимости удаляем дубликаты Если ТолькоУникальные Тогда Результат = RemoveDuplicates(Результат); КонецЕсли; Возврат Результат; КонецФункции // Создает новый массив, удаляя дубликаты из исходного массива /// Исходный массив /// Массив без дубликатов Функция RemoveDuplicates(Массив) Экспорт Результат = Новый Массив; // Оптимизация: используем Соответствие вместо Массив.Найти() УникальныеЗначения = Новый Соответствие; Для Каждого Элемент Из Массив Цикл Если УникальныеЗначения[Элемент] = Неопределено Тогда Результат.Добавить(Элемент); УникальныеЗначения.Вставить(Элемент, Истина); КонецЕсли; КонецЦикла; Возврат Результат; КонецФункции /// Объединение множеств до 8 массивов - всегда возвращает только уникальные значения Функция Union(Массив1, Массив2 = Неопределено, Массив3 = Неопределено, Массив4 = Неопределено, Массив5 = Неопределено, Массив6 = Неопределено, Массив7 = Неопределено, Массив8 = Неопределено) Экспорт Возврат Concatenate(Массив1, Массив2, Массив3, Массив4, Массив5, Массив6, Массив7, Массив8, Истина); КонецФункции /// Возвращает элементы, которые есть во всех переданных массивах (пересечение до 8 массивов) Функция Intersection(Массив1, Массив2 = Неопределено, Массив3 = Неопределено, Массив4 = Неопределено, Массив5 = Неопределено, Массив6 = Неопределено, Массив7 = Неопределено, Массив8 = Неопределено) Экспорт // Создаем массив всех переданных массивов ВсеМассивы = Новый Массив; Если Массив1 <> Неопределено Тогда ВсеМассивы.Добавить(Массив1); КонецЕсли; Если Массив2 <> Неопределено Тогда ВсеМассивы.Добавить(Массив2); КонецЕсли; Если Массив3 <> Неопределено Тогда ВсеМассивы.Добавить(Массив3); КонецЕсли; Если Массив4 <> Неопределено Тогда ВсеМассивы.Добавить(Массив4); КонецЕсли; Если Массив5 <> Неопределено Тогда ВсеМассивы.Добавить(Массив5); КонецЕсли; Если Массив6 <> Неопределено Тогда ВсеМассивы.Добавить(Массив6); КонецЕсли; Если Массив7 <> Неопределено Тогда ВсеМассивы.Добавить(Массив7); КонецЕсли; Если Массив8 <> Неопределено Тогда ВсеМассивы.Добавить(Массив8); КонецЕсли; Если ВсеМассивы.Количество() = 0 Тогда Возврат Новый Массив; КонецЕсли; Если ВсеМассивы.Количество() = 1 Тогда Возврат RemoveDuplicates(ВсеМассивы[0]); КонецЕсли; // Начинаем с первого массива Результат = RemoveDuplicates(ВсеМассивы[0]); // Последовательно пересекаем с каждым следующим массивом Для Индекс = 1 По ВсеМассивы.Количество() - 1 Цикл ТекущийМассив = ВсеМассивы[Индекс]; Элементы = Новый Соответствие; Для Каждого Элемент Из ТекущийМассив Цикл Элементы.Вставить(Элемент, Истина); КонецЦикла; НовыйРезультат = Новый Массив; Для Каждого Элемент Из Результат Цикл Если Элементы[Элемент] <> Неопределено Тогда НовыйРезультат.Добавить(Элемент); КонецЕсли; КонецЦикла; Результат = НовыйРезультат; КонецЦикла; Возврат Результат; КонецФункции /// Возвращает элементы из первого массива, которых нет в остальных массивах (разность до 8 массивов) Функция Difference(Массив1, Массив2 = Неопределено, Массив3 = Неопределено, Массив4 = Неопределено, Массив5 = Неопределено, Массив6 = Неопределено, Массив7 = Неопределено, Массив8 = Неопределено) Экспорт Если Массив1 = Неопределено Тогда Возврат Новый Массив; КонецЕсли; // Создаем массив массивов для исключения МассивыИсключения = Новый Массив; Если Массив2 <> Неопределено Тогда МассивыИсключения.Добавить(Массив2); КонецЕсли; Если Массив3 <> Неопределено Тогда МассивыИсключения.Добавить(Массив3); КонецЕсли; Если Массив4 <> Неопределено Тогда МассивыИсключения.Добавить(Массив4); КонецЕсли; Если Массив5 <> Неопределено Тогда МассивыИсключения.Добавить(Массив5); КонецЕсли; Если Массив6 <> Неопределено Тогда МассивыИсключения.Добавить(Массив6); КонецЕсли; Если Массив7 <> Неопределено Тогда МассивыИсключения.Добавить(Массив7); КонецЕсли; Если Массив8 <> Неопределено Тогда МассивыИсключения.Добавить(Массив8); КонецЕсли; // Создаем соответствие всех элементов для исключения ЭлементыИсключения = Новый Соответствие; Для Каждого МассивИсключения Из МассивыИсключения Цикл Для Каждого Элемент Из МассивИсключения Цикл ЭлементыИсключения.Вставить(Элемент, Истина); КонецЦикла; КонецЦикла; // Формируем результат Результат = Новый Массив; Для Каждого Элемент Из Массив1 Цикл Если ЭлементыИсключения[Элемент] = Неопределено Тогда Результат.Добавить(Элемент); КонецЕсли; КонецЦикла; Возврат Результат; КонецФункции #КонецОбласти #Область ФильтрацияИТипизация /// ✦ PickByType — Выбрать элементы определённого типа /// ➤ Array (Массив) — Исходный массив /// ➤ TypeOrTypes (Тип, Массив, ОписаниеТипов) — Тип или массив типов /// ⬅ Массив — Элементы указанного типа (типов) /// /// Примеры: /// Числа = A1sAR.PickByType(Смешанный, Тип("Число")); /// ЧислаИСтроки = A1sAR.PickByType(Смешанный, A1sAR.Of(Тип("Число"), Тип("Строка"))); /// Функция PickByType(Array, TypeOrTypes) Экспорт ib = "Выбирает элементы массива по типу"; Результат = Новый Массив; //✏ ТипАргумента = ТипЗнч(TypeOrTypes); Если ТипАргумента = Тип("Тип") Тогда //⚡ Для Каждого Элемент Из Array Цикл //⟳ Если ТипЗнч(Элемент) = TypeOrTypes Тогда //⚡ Результат.Добавить(Элемент); КонецЕсли; КонецЦикла; ИначеЕсли ТипАргумента = Тип("Массив") Тогда //⚡ Для Каждого Элемент Из Array Цикл //⟳ Если TypeOrTypes.Найти(ТипЗнч(Элемент)) <> Неопределено Тогда //⚡ Результат.Добавить(Элемент); КонецЕсли; КонецЦикла; ИначеЕсли ТипАргумента = Тип("ОписаниеТипов") Тогда //⚡ Для Каждого Элемент Из Array Цикл //⟳ Если TypeOrTypes.СодержитТип(ТипЗнч(Элемент)) Тогда //⚡ Результат.Добавить(Элемент); КонецЕсли; КонецЦикла; КонецЕсли; Возврат Результат; //↩ КонецФункции /// ✦ OmitByType — Все элементы КРОМЕ указанного типа /// ➤ Array (Массив) — Исходный массив /// ➤ TypeOrTypes (Тип, Массив, ОписаниеТипов) — Тип для исключения /// ⬅ Массив — Элементы БЕЗ указанного типа /// Функция OmitByType(Array, TypeOrTypes) Экспорт ib = "Возвращает элементы массива кроме указанного типа"; Результат = Новый Массив; //✏ Если ТипЗнч(TypeOrTypes) = Тип("Тип") Тогда //⚡ Для Каждого Элемент Из Array Цикл //⟳ Если ТипЗнч(Элемент) <> TypeOrTypes Тогда //⚡ Результат.Добавить(Элемент); КонецЕсли; КонецЦикла; ИначеЕсли ТипЗнч(TypeOrTypes) = Тип("Массив") Тогда //⚡ Для Каждого Элемент Из Array Цикл //⟳ Если TypeOrTypes.Найти(ТипЗнч(Элемент)) = Неопределено Тогда //⚡ Результат.Добавить(Элемент); КонецЕсли; КонецЦикла; ИначеЕсли ТипЗнч(TypeOrTypes) = Тип("ОписаниеТипов") Тогда //⚡ Для Каждого Элемент Из Array Цикл //⟳ Если НЕ TypeOrTypes.СодержитТип(ТипЗнч(Элемент)) Тогда //⚡ Результат.Добавить(Элемент); КонецЕсли; КонецЦикла; КонецЕсли; Возврат Результат; //↩ КонецФункции /// ✦ PickRefs — Выбрать только ссылки (справочники, документы и т.д.) /// ➤ Array (Массив) — Исходный массив /// ⬅ Массив — Только ссылочные элементы /// Функция PickRefs(Array) Экспорт ib = "Выбирает только ссылочные элементы массива"; Результат = Новый Массив; //✏ Для Каждого Элемент Из Array Цикл //⟳ ИмяТипа = Строка(ТипЗнч(Элемент)); //✏ Если СтрНайти(ИмяТипа, "Ссылка") > 0 Тогда //⚡ Результат.Добавить(Элемент); КонецЕсли; КонецЦикла; Возврат Результат; //↩ КонецФункции /// ✦ PickFilled — Выбрать только заполненные значения /// ➤ Array (Массив) — Исходный массив /// ⬅ Массив — Только заполненные элементы /// Функция PickFilled(Array) Экспорт ib = "Выбирает только заполненные элементы массива"; Результат = Новый Массив; //✏ Для Каждого Элемент Из Array Цикл //⟳ Если ЗначениеЗаполнено(Элемент) Тогда //⚡ Результат.Добавить(Элемент); КонецЕсли; КонецЦикла; Возврат Результат; //↩ КонецФункции /// ✦ PickNotNull — Выбрать всё кроме Неопределено /// ➤ Array (Массив) — Исходный массив /// ⬅ Массив — Элементы без Неопределено /// Функция PickNotNull(Array) Экспорт ib = "Выбирает элементы кроме Неопределено"; Результат = Новый Массив; //✏ Для Каждого Элемент Из Array Цикл //⟳ Если Элемент <> Неопределено Тогда //⚡ Результат.Добавить(Элемент); КонецЕсли; КонецЦикла; Возврат Результат; //↩ КонецФункции // Анализ типов // // Собирает все типы значений массива в массив уникальных типов. ✦ // Исходный массив ➤ // Array — массив объектов типа Тип ⬅ // Функция GetTypes(Array) Экспорт //⚙ ib = "A1sAR: Получение списка типов элементов массива"; //✍ TypesArray = Новый Массив; //✏ Для Каждого Element Из Array Цикл //⟳ TypesArray.Добавить(ТипЗнч(Element)); //✏ КонецЦикла; Возврат RemoveDuplicates(TypesArray); //↩ КонецФункции // // Проверяет, являются ли все элементы массива значениями одного типа. ✦ // Исходный массив ➤ // Boolean — Истина, если все элементы одного типа (или массив пуст) ⬅ // Функция IsHomoTyped(Array) Экспорт //⚙ ib = "A1sAR: Проверка массива на однородность типов"; //✍ Если Array.Количество() <= 1 Тогда //⚡ Возврат Истина; //↩ КонецЕсли; FirstType = ТипЗнч(Array[0]); //✏ Для i = 1 По Array.Количество() - 1 Цикл //⟳ Если ТипЗнч(Array[i]) <> FirstType Тогда //⚡ Возврат Ложь; //↩ КонецЕсли; КонецЦикла; Возврат Истина; //↩ КонецФункции // // Группирует элементы массива по их типам. ✦ // Исходный массив ➤ // Structure — Ключи: Имена типов, Значения: Массивы элементов ⬅ // Функция GroupByType(Array) Экспорт //⚙ ib = "A1sAR: Группировка массива по типам"; //✍ Result = Новый Структура; //✏ Для Каждого Element Из Array Цикл //⟳ TypeName = СтрЗаменить(Строка(ТипЗнч(Element)), " ", ""); //✏ Если НЕ Result.Свойство(TypeName) Тогда //⚡ Result.Вставить(TypeName, Новый Массив); //✏ КонецЕсли; Result[TypeName].Добавить(Element); //✏ КонецЦикла; Возврат Result; //↩ КонецФункции // // Определяет тип, который встречается в массиве чаще всего. ✦ // Исходный массив ➤ // Type — Самый часто встречающийся тип ⬅ // Функция MostFrequentType(Array) Экспорт //⚙ ib = "A1sAR: Поиск доминирующего типа в массиве"; //✍ Если Array.Количество() = 0 Тогда //⚡ Возврат Неопределено; //↩ КонецЕсли; Stats = Новый Соответствие; //✏ MaxCount = 0; //✏ WinnerType = Неопределено; //✏ Для Каждого Element Из Array Цикл //⟳ CurrentType = ТипЗнч(Element); Count = Stats[CurrentType]; Count = ?(Count = Неопределено, 1, Count + 1); Stats.Вставить(CurrentType, Count); Если Count > MaxCount Тогда //⚡ MaxCount = Count; WinnerType = CurrentType; КонецЕсли; КонецЦикла; Возврат WinnerType; //↩ КонецФункции // // // Преобразует гетерогенный массив в массив, гомогенный по типу. // Каждый элемент приводится к указанному типу. // Если преобразование невозможно — используется DefaultValue. // ✦ // // Исходный массив с элементами произвольных типов // ➤ // // Тип, к которому требуется привести элементы // (например, Тип("Число"), Тип("Дата")) // ➤ // // Значение, подставляемое при невозможности преобразования // ➤ // // Array — новый массив, гомогенный по типу // ⬅ // // Функция ConvertTo(SourceArray, TargetType, DefaultValue = Неопределено) Экспорт Если ТипЗнч(SourceArray) <> Тип("Массив") Тогда Возврат Новый Массив; КонецЕсли; Результат = Новый Массив; // ОписаниеТипов НЕ принимает Тип напрямую — оборачиваем в массив Типы = Новый Массив; Типы.Добавить(TargetType); ОписаниеТипа = Новый ОписаниеТипов(Типы); Для Каждого Элемент Из SourceArray Цикл Если ТипЗнч(Элемент) = TargetType Тогда Результат.Добавить(Элемент); Продолжить; КонецЕсли; Попытка Преобразованное = ОписаниеТипа.ПривестиЗначение(Элемент); Результат.Добавить(Преобразованное); Исключение Результат.Добавить(DefaultValue); КонецПопытки; КонецЦикла; Возврат Результат; КонецФункции #КонецОбласти #Область ДоступИАгрегация /// Возвращает первый элемент массива или Неопределено Функция First(Массив) Экспорт Если Массив.Количество() > 0 Тогда Возврат Массив[0]; Иначе Возврат Неопределено; КонецЕсли; КонецФункции /// Возвращает последний элемент массива или Неопределено Функция Last(Массив) Экспорт Если Массив.Количество() > 0 Тогда Возврат Массив[Массив.Количество() - 1]; Иначе Возврат Неопределено; КонецЕсли; КонецФункции /// Проверяет, содержит ли массив указанное значение Функция Contains(Массив, Значение) Экспорт Возврат Массив.Найти(Значение) <> Неопределено; КонецФункции /// Возвращает индекс первого вхождения элемента в массив, или -1 если не найден Функция IndexOf(Массив, Значение) Экспорт Для Счет = 0 По Массив.Количество() - 1 Цикл Если Массив[Счет] = Значение Тогда Возврат Счет; КонецЕсли; КонецЦикла; Возврат -1; КонецФункции /// Объединяет элементы массива в строку с указанным разделителем Функция Join(Массив, Разделитель) Экспорт Если Массив.Количество() = 0 Тогда Возврат ""; КонецЕсли; Результат = ""; Для Счет = 0 По Массив.Количество() - 1 Цикл Результат = Результат + Формат(Массив[Счет]); Если Счет < Массив.Количество() - 1 Тогда Результат = Результат + Разделитель; КонецЕсли; КонецЦикла; Возврат Результат; КонецФункции /// Проверяет, пуст ли массив (нет элементов) Функция IsEmpty(Массив) Экспорт Возврат Массив.Количество() = 0; КонецФункции // Добавляет значение в массив по условию. // // Параметры: // Массив - Массив - массив, в который нужно добавить значение. // ЗначениеЕслиИстина - Произвольный - значение для добавления при истинном условии. // Условие - Булево - условие добавления значения. // ЗначениеЕслиЛожь - Произвольный - значение для добавления при ложном условии. // // Возвращаемое значение: // Массив - переданный массив с добавленным значением или без изменений. // Функция AddIf(Массив, ЗначениеЕслиИстина, Условие = Истина, ЗначениеЕслиЛожь = Неопределено) Экспорт Если Условие Тогда Массив.Добавить(ЗначениеЕслиИстина); ИначеЕсли ЗначениеЕслиЛожь <> Неопределено Тогда Массив.Добавить(ЗначениеЕслиЛожь); КонецЕсли; Возврат Массив; КонецФункции #КонецОбласти #Область СравнениеИСлужебное // // // Сравнивает два массива примитивных значений на точное равенство. // Сравнение выполняется поэлементно оператором <>. // ✦ // Первый массив ➤ // Второй массив ➤ // Boolean ⬅ // // Функция Equals(Array1, Array2) Экспорт Если ТипЗнч(Array1) <> Тип("Массив") ИЛИ ТипЗнч(Array2) <> Тип("Массив") Тогда Возврат Ложь; КонецЕсли; Если Array1.Количество() <> Array2.Количество() Тогда Возврат Ложь; КонецЕсли; Для i = 0 По Array1.Количество() - 1 Цикл Если Array1[i] = Неопределено И Array2[i] = Неопределено Тогда Продолжить; КонецЕсли; Если Array1[i] <> Array2[i] Тогда Возврат Ложь; КонецЕсли; КонецЦикла; Возврат Истина; КонецФункции // // // Глубокое сравнение двух массивов по значению. // Поддерживает вложенные массивы, структуры и соответствия. // ✦ // Первый массив ➤ // Второй массив ➤ // Boolean ⬅ // // Функция EqualsDeep(Array1, Array2) Экспорт Если ТипЗнч(Array1) <> Тип("Массив") ИЛИ ТипЗнч(Array2) <> Тип("Массив") Тогда Возврат Ложь; КонецЕсли; Возврат EqualsDeepValue(Array1, Array2); КонецФункции Функция EqualsDeepValue(Value1, Value2) // Быстрое равенство (включая Неопределено) Если Value1 = Value2 Тогда Возврат Истина; КонецЕсли; Тип1 = ТипЗнч(Value1); Тип2 = ТипЗнч(Value2); Если Тип1 <> Тип2 Тогда Возврат Ложь; КонецЕсли; // === МАССИВ === Если Тип1 = Тип("Массив") Тогда Если Value1.Количество() <> Value2.Количество() Тогда Возврат Ложь; КонецЕсли; Для i = 0 По Value1.Количество() - 1 Цикл Если НЕ EqualsDeepValue(Value1[i], Value2[i]) Тогда Возврат Ложь; КонецЕсли; КонецЦикла; Возврат Истина; КонецЕсли; // === СТРУКТУРА === Если Тип1 = Тип("Структура") Тогда Если Value1.Количество() <> Value2.Количество() Тогда Возврат Ложь; КонецЕсли; Для Каждого Ключ Из Value1 Цикл Если НЕ Value2.Свойство(Ключ) Тогда Возврат Ложь; КонецЕсли; Если НЕ EqualsDeepValue(Value1[Ключ], Value2[Ключ]) Тогда Возврат Ложь; КонецЕсли; КонецЦикла; Возврат Истина; КонецЕсли; // === СООТВЕТСТВИЕ === Если Тип1 = Тип("Соответствие") Тогда Если Value1.Количество() <> Value2.Количество() Тогда Возврат Ложь; КонецЕсли; Для Каждого Ключ Из Value1 Цикл Если НЕ Value2.СодержитКлюч(Ключ) Тогда Возврат Ложь; КонецЕсли; Если НЕ EqualsDeepValue(Value1[Ключ], Value2[Ключ]) Тогда Возврат Ложь; КонецЕсли; КонецЦикла; Возврат Истина; КонецЕсли; // === ПРИМИТИВЫ === Возврат Value1 = Value2; КонецФункции // // Создаёт fluent-обёртку над массивом для цепочечных вызовов. ✦ // Массив для обёртки (необязательный) ➤ // ОбработкаОбъект.A1sDP_AR — fluent-обёртка ⬅ // // // // Цепочечный вызов: // Результат = A1sAR.On() // .Add(1).Add(2).Add(3) // .RemoveDuplicates() // .Sort() // .Value(); // // // С начальным массивом: // Результат = A1sAR.On(СуществующийМассив) // .Concatenate(ДругойМассив) // .Reverse() // .Value(); // // WORKS ONLY &AtServer. DUE TO PROCESSING VISIBILITY SCOPE // &AtServer Функция On(ИсходныйМассив = Неопределено) Экспорт //⚙ //ib = "Создание fluent-обёртки для массива"; //✍ Обёртка = Обработки.A1sDP_AR.Создать(); //✏ Если ИсходныйМассив <> Неопределено И ТипЗнч(ИсходныйМассив)=Тип("Массив") Тогда //⚡ Обёртка.УстановитьДанные(ИсходныйМассив); //▶️ КонецЕсли; Возврат Обёртка; //↩ КонецФункции #КонецОбласти #Область ТестыИПримеры // // Самотест модуля A1sAR с примерами использования. ✦ // Boolean — все тесты пройдены успешно ⬅ // // Функция SelfTest() Экспорт //⚙ Переименовано с OfN_SelfTest ib = "Самотест A1sAR"; //✍ TestsPassed = 0; //✏ TestsTotal = 0; //✏ Сообщить("=== A1sAR.SelfTest() START ==="); // --- ГРУППА 1: OfN и Fill (старые тесты) --- // Тест 1: OfN с числовым значением TestsTotal = TestsTotal + 1; //✏ TestArray1 = OfN(5, 42); //✏ Если TestArray1.Количество() = 5 И TestArray1[0] = 42 И TestArray1[4] = 42 Тогда //⚡ TestsPassed = TestsPassed + 1; //✏ // Сообщить("✓ Тест 1 (OfN числовое): ПРОЙДЕН"); Иначе Сообщить("✗ Тест 1 (OfN числовое): ПРОВАЛЕН"); КонецЕсли; // Тест 2: OfN со строковым значением TestsTotal = TestsTotal + 1; //✏ TestArray2 = OfN(3, "test"); //✏ Если TestArray2.Количество() = 3 И TestArray2[0] = "test" И TestArray2[2] = "test" Тогда //⚡ TestsPassed = TestsPassed + 1; //✏ Иначе Сообщить("✗ Тест 2 (OfN строковое): ПРОВАЛЕН"); КонецЕсли; // Тест 3: OfN с нулевым размером TestsTotal = TestsTotal + 1; //✏ TestArray3 = OfN(0, "empty"); //✏ Если TestArray3.Количество() = 0 Тогда //⚡ TestsPassed = TestsPassed + 1; //✏ Иначе Сообщить("✗ Тест 3 (OfN пустой): ПРОВАЛЕН"); КонецЕсли; // Тест 4: OfN с отрицательным размером TestsTotal = TestsTotal + 1; //✏ TestArray4 = OfN(-5, "negative"); //✏ Если TestArray4.Количество() = 0 Тогда //⚡ TestsPassed = TestsPassed + 1; //✏ Иначе Сообщить("✗ Тест 4 (OfN отрицательный): ПРОВАЛЕН"); КонецЕсли; // Тест 5: Fill существующего массива TestsTotal = TestsTotal + 1; //✏ TestArray5 = Новый Массив(); //✏ TestArray5.Добавить(1); TestArray5.Добавить(2); TestArray5.Добавить(3); FillResult = Fill(TestArray5, "filled"); //✏ Если FillResult И TestArray5.Количество() = 3 И TestArray5[0] = "filled" И TestArray5[2] = "filled" Тогда //⚡ TestsPassed = TestsPassed + 1; //✏ Иначе Сообщить("✗ Тест 5 (Fill массива): ПРОВАЛЕН"); КонецЕсли; // Тест 6: Fill с неправильным параметром TestsTotal = TestsTotal + 1; //✏ FillResult2 = Fill("не массив", "error"); //✏ Если НЕ FillResult2 Тогда //⚡ TestsPassed = TestsPassed + 1; //✏ Иначе Сообщить("✗ Тест 6 (Fill ошибка): ПРОВАЛЕН"); КонецЕсли; // --- ГРУППА 2: Структурирование (Chunk, Flatten, Insert, RemoveAt) --- // Тест 7: Chunk (разбиение ровно) TestsTotal = TestsTotal + 1; Arr7 = Of(1, 2, 3, 4, 5, 6); Res7 = Chunk(Arr7, 2); Если Res7.Количество() = 3 И Res7[0].Количество() = 2 И Res7[2].Количество() = 2 Тогда TestsPassed = TestsPassed + 1; Иначе Сообщить("✗ Тест 7 (Chunk ровно): ПРОВАЛЕН"); КонецЕсли; // Тест 8: Chunk (разбиение с остатком) TestsTotal = TestsTotal + 1; Arr8 = Of(1, 2, 3, 4, 5); Res8 = Chunk(Arr8, 2); Если Res8.Количество() = 3 И Res8[2].Количество() = 1 И Res8[2][0] = 5 Тогда TestsPassed = TestsPassed + 1; Иначе Сообщить("✗ Тест 8 (Chunk остаток): ПРОВАЛЕН"); КонецЕсли; // Тест 9: Flatten (выравнивание) TestsTotal = TestsTotal + 1; Arr9 = Of(1, Of(2, 3), 4); Res9 = Flatten(Arr9); Если Res9.Количество() = 4 И Res9[0] = 1 И Res9[1] = 2 И Res9[2] = 3 И Res9[3] = 4 Тогда TestsPassed = TestsPassed + 1; Иначе Сообщить("✗ Тест 9 (Flatten): ПРОВАЛЕН"); КонецЕсли; // Тест 10: Insert (вставка в середину) TestsTotal = TestsTotal + 1; Arr10 = Of(1, 3); Res10 = Insert(Arr10, 1, 2); Если Res10.Количество() = 3 И Res10[1] = 2 И Res10[2] = 3 Тогда TestsPassed = TestsPassed + 1; Иначе Сообщить("✗ Тест 10 (Insert середина): ПРОВАЛЕН"); КонецЕсли; // Тест 11: Insert (вставка в конец) TestsTotal = TestsTotal + 1; Arr11 = Of(1); Res11 = Insert(Arr11, 10, 2); // Индекс за пределами, должно добавить в конец Если Res11.Количество() = 2 И Res11[1] = 2 Тогда TestsPassed = TestsPassed + 1; Иначе Сообщить("✗ Тест 11 (Insert конец): ПРОВАЛЕН"); КонецЕсли; // Тест 12: RemoveAt (удаление из середины) TestsTotal = TestsTotal + 1; Arr12 = Of(1, 2, 3); Res12 = RemoveAt(Arr12, 1); Если Res12.Количество() = 2 И Res12[0] = 1 И Res12[1] = 3 Тогда TestsPassed = TestsPassed + 1; Иначе Сообщить("✗ Тест 12 (RemoveAt середина): ПРОВАЛЕН"); КонецЕсли; // Тест 13: RemoveAt (неверный индекс - безопасное поведение) TestsTotal = TestsTotal + 1; Arr13 = Of(1, 2, 3); Res13 = RemoveAt(Arr13, 10); Если Res13.Количество() = 3 И Res13 = Arr13 Тогда // Должен вернуть копию, но идентичную по содержимому TestsPassed = TestsPassed + 1; Иначе Сообщить("✗ Тест 13 (RemoveAt неверный индекс): ПРОВАЛЕН"); КонецЕсли; // --- ИТОГИ --- Если TestsPassed = TestsTotal Тогда //⚡ Сообщить("=== A1sAR.SelfTest() SUCCESS: " + Строка(TestsPassed) + "/" + Строка(TestsTotal) + " ==="); Возврат Истина; //↩ Иначе Сообщить("=== A1sAR.SelfTest() FAILED: " + Строка(TestsPassed) + "/" + Строка(TestsTotal) + " ==="); Возврат Ложь; //↩ КонецЕсли; КонецФункции // // Расширенные примеры использования функций модуля A1sAR. ✦ // Процедура ExamplesAdvanced() Экспорт //⚙ Переименовано с OfN_... ib = "Примеры A1sAR"; //✍ Сообщить("=== Примеры использования A1sAR ==="); // Пример 1: Создание массива с булевыми значениями BoolArray = OfN(4, Истина); //✏ Сообщить("Массив булевых (4 элемента): " + Строка(BoolArray.Количество()) + " элементов"); // Пример 2: Массив структур EmptyStruct = Новый Структура(); //✏ StructArray = OfN(2, EmptyStruct); //✏ Сообщить("Массив структур: " + Строка(StructArray.Количество()) + " элементов"); // Пример 3: Заполнение существующего массива датой DateArray = Новый Массив(); //✏ DateArray.Добавить('20240101'); //✏ DateArray.Добавить('20240201'); //✏ DateArray.Добавить('20240301'); //✏ CurrentDate = ТекущаяДата(); //✏ Fill(DateArray, CurrentDate); //✏ Сообщить("Массив дат заполнен текущей датой: " + Строка(DateArray.Количество()) + " элементов"); // Пример 4: Создание матрицы (массив массивов) MatrixRow = OfN(3, 0); //✏ Matrix = OfN(2, MatrixRow); //✏ Сообщить("Матрица 2x3 создана: " + Строка(Matrix.Количество()) + " строк"); // Пример 5: Chunk (Разбиение) BigArray = OfN(10, "x"); Chunks = Chunk(BigArray, 3); Сообщить("Массив разбит на чанки: " + Строка(Chunks.Количество()) + " штук"); // Пример 6: Insert (Вставка) Letters = Of("A", "C"); Letters = Insert(Letters, 1, "B"); Сообщить("После вставки: " + Join(Letters, "")); Сообщить("=== Примеры завершены ==="); КонецПроцедуры #КонецОбласти #Область СериализацияИСанация // // // Преобразует массив в JSON-строку. // ⚠️ ВНИМАНИЕ: Строгий режим. Данные должны быть очищены через Sanitize заранее. // // Исходный массив ➤ // String — JSON строка ⬅ // // Dirty = ПолучитьГрязныйМассив(); // Clean = A1sAR.Sanitize(Dirty); // JSON = A1sAR.ToJSON(Clean); // ✅ Быстро и безопасно // // Функция ToJSON(Массив) Экспорт // ✅ STRICT MODE: Пишем как есть. Никакого автоматического Sanitize. // Это обеспечивает максимальную производительность для чистых данных. ЗаписьJSON = Новый ЗаписьJSON; // Можно добавить красивое форматирование по умолчанию ПараметрыЗаписи = Новый ПараметрыЗаписиJSON(ПереносСтрокJSON.Нет, Символы.Табуляция); ЗаписьJSON.УстановитьСтроку(ПараметрыЗаписи); ЗаписатьJSON(ЗаписьJSON, Массив); // <-- Падет, если там есть Ссылка! Возврат ЗаписьJSON.Закрыть(); КонецФункции // // // Очистка массива от несовместимых с JSON типов. // // Исходный массив ➤ // Array — Чистый массив ⬅ // &AtServer Функция Sanitize(Массив) Экспорт Возврат A1sDS.Sanitize(Массив); // Делегируем ядру КонецФункции #КонецОбласти