////////////////////////////////////////////////////////////////////////////////
// Обработка: A1sDP_AR
// Назначение:
// Fluent-обёртка над массивом для цепочечных вызовов.
// Все методы возвращают ЭтотОбъект для поддержки chaining.
//
// Использование:
// A1sAR.On().Add(1).Add(2).Sort().Value()
//
// Автор: A1sCode (a1scode.ru)
// Версия: 2.0
// Дата: 2026-01
////////////////////////////////////////////////////////////////////////////////
#Область ОписаниеПеременных
Перем Данные; // Массив — внутреннее хранилище
#КонецОбласти
#Область ПрограммныйИнтерфейс
//
// Возвращает внутренний массив (завершение цепочки). ✦
// Array — результирующий массив ⬅
//
Функция Value() Экспорт //⚙
Возврат Данные; //↩
КонецФункции
//
// Устанавливает внутренний массив. ✦
// Массив для установки ➤
// ОбработкаОбъект.A1sDP_AR — ЭтотОбъект для chaining ⬅
//
Функция УстановитьДанные(НовыйМассив) Экспорт //⚙
Данные = НовыйМассив; //✏
Возврат ЭтотОбъект; //↩
КонецФункции
//
// Добавляет элемент в массив. ✦
// Значение для добавления ➤
// ОбработкаОбъект.A1sDP_AR — ЭтотОбъект ⬅
//
Функция Add(Значение) Экспорт //⚙
Данные.Добавить(Значение); //✏
Возврат ЭтотОбъект; //↩
КонецФункции
//
// Добавляет элемент по условию. ✦
//
Функция AddIf(ЗначениеЕслиИстина, Условие = Истина, ЗначениеЕслиЛожь = Неопределено) Экспорт //⚙
A1sAR.AddIf(Данные, ЗначениеЕслиИстина, Условие, ЗначениеЕслиЛожь); //▶️
Возврат ЭтотОбъект; //↩
КонецФункции
//
// Объединяет с другими массивами. ✦
//
Функция Concatenate(Массив2 = Неопределено, Массив3 = Неопределено, Массив4 = Неопределено,
Массив5 = Неопределено, Массив6 = Неопределено, Массив7 = Неопределено,
Массив8 = Неопределено, ТолькоУникальные = Ложь) Экспорт //⚙
Данные = A1sAR.Concatenate(Данные, Массив2, Массив3, Массив4, Массив5, Массив6, Массив7, Массив8, ТолькоУникальные); //✏
Возврат ЭтотОбъект; //↩
КонецФункции
//
// Объединение множеств (только уникальные). ✦
//
Функция Union(Массив2 = Неопределено, Массив3 = Неопределено, Массив4 = Неопределено,
Массив5 = Неопределено, Массив6 = Неопределено, Массив7 = Неопределено,
Массив8 = Неопределено) Экспорт //⚙
Данные = A1sAR.Union(Данные, Массив2, Массив3, Массив4, Массив5, Массив6, Массив7, Массив8); //✏
Возврат ЭтотОбъект; //↩
КонецФункции
//
// Пересечение с другими массивами. ✦
//
Функция Intersection(Массив2 = Неопределено, Массив3 = Неопределено, Массив4 = Неопределено,
Массив5 = Неопределено, Массив6 = Неопределено, Массив7 = Неопределено,
Массив8 = Неопределено) Экспорт //⚙
Данные = A1sAR.Intersection(Данные, Массив2, Массив3, Массив4, Массив5, Массив6, Массив7, Массив8); //✏
Возврат ЭтотОбъект; //↩
КонецФункции
//
// Разность: элементы из текущего массива, которых нет в других. ✦
//
Функция Difference(Массив2 = Неопределено, Массив3 = Неопределено, Массив4 = Неопределено,
Массив5 = Неопределено, Массив6 = Неопределено, Массив7 = Неопределено,
Массив8 = Неопределено) Экспорт //⚙
Данные = A1sAR.Difference(Данные, Массив2, Массив3, Массив4, Массив5, Массив6, Массив7, Массив8); //✏
Возврат ЭтотОбъект; //↩
КонецФункции
//
// Удаляет дубликаты. ✦
//
Функция RemoveDuplicates() Экспорт //⚙
Данные = A1sAR.RemoveDuplicates(Данные); //✏
Возврат ЭтотОбъект; //↩
КонецФункции
//
// Сортирует по возрастанию. ✦
//
Функция Sort() Экспорт //⚙
Данные = A1sAR.Sort(Данные); //✏
Возврат ЭтотОбъект; //↩
КонецФункции
//
// Разворачивает массив. ✦
//
Функция Reverse() Экспорт //⚙
Данные = A1sAR.Reverse(Данные); //✏
Возврат ЭтотОбъект; //↩
КонецФункции
//
// Заполняет все элементы одним значением. ✦
//
Функция Fill(Значение) Экспорт //⚙
A1sAR.Fill(Данные, Значение); //▶️
Возврат ЭтотОбъект; //↩
КонецФункции
//
// Вставляет элемент по индексу. ✦
//
Функция Insert(Индекс, Значение) Экспорт //⚙
Данные = A1sAR.Insert(Данные, Индекс, Значение); //✏
Возврат ЭтотОбъект; //↩
КонецФункции
//
// Удаляет элемент по индексу. ✦
//
Функция RemoveAt(Индекс) Экспорт //⚙
Данные = A1sAR.RemoveAt(Данные, Индекс); //✏
Возврат ЭтотОбъект; //↩
КонецФункции
#КонецОбласти
#Область ТерминаторыЦепочки
// Эти методы НЕ возвращают ЭтотОбъект — они завершают цепочку
//
// Проверяет наличие значения. ✦
// Boolean ⬅
//
Функция Contains(Значение) Экспорт //⚙
Возврат A1sAR.Contains(Данные, Значение); //↩
КонецФункции
//
// Первый элемент или Неопределено. ✦
//
Функция First() Экспорт //⚙
Возврат A1sAR.First(Данные); //↩
КонецФункции
//
// Последний элемент или Неопределено. ✦
//
Функция Last() Экспорт //⚙
Возврат A1sAR.Last(Данные); //↩
КонецФункции
//
// Индекс элемента или -1. ✦
//
Функция IndexOf(Значение) Экспорт //⚙
Возврат A1sAR.IndexOf(Данные, Значение); //↩
КонецФункции
//
// Объединяет в строку. ✦
//
Функция Join(Разделитель = ",") Экспорт //⚙
Возврат A1sAR.Join(Данные, Разделитель); //↩
КонецФункции
//
// Проверяет, пуст ли массив. ✦
//
Функция IsEmpty() Экспорт //⚙
Возврат A1sAR.IsEmpty(Данные); //↩
КонецФункции
//
// Количество элементов. ✦
//
Функция Count() Экспорт //⚙
Возврат Данные.Количество(); //↩
КонецФункции
#КонецОбласти
////////////////////////////////////////////////////////////////////////////////
// ДОПОЛНЕНИЕ к обработке A1sDP_AR
// Недостающие методы для соответствия Fluent API
//
// Добавить эти методы в существующую обработку A1sDP_AR
// в секцию #Область ПрограммныйИнтерфейс
////////////////////////////////////////////////////////////////////////////////
#Область ДополнительныеТрансформаторы
/// ✦ AddAll — Добавить все элементы из другого массива
/// ➤ Массив (Массив) — Массив элементов для добавления
/// ⬅ A1sDP_AR — ЭтотОбъект для цепочки вызовов
///
/// Пример:
/// A1sAR.On().Add(1).AddAll(A1sAR.Of(2, 3, 4)).Value();
/// // [1, 2, 3, 4]
///
Функция AddAll(Знач Массив) Экспорт
ib = "Добавление всех элементов из массива"; //⚙
Если ТипЗнч(Массив) = Тип("Массив") ИЛИ ТипЗнч(Массив) = Тип("ФиксированныйМассив") Тогда //⚡
Для Каждого Элемент Из Массив Цикл //⟳
Данные.Добавить(Элемент); //✏
КонецЦикла;
КонецЕсли;
Возврат ЭтотОбъект; //↩
КонецФункции
/// ✦ RemoveValue — Удалить первое вхождение значения
/// ➤ Значение (Произвольный) — Значение для удаления
/// ⬅ A1sDP_AR — ЭтотОбъект для цепочки вызовов
///
/// Пример:
/// A1sAR.On(A1sAR.Of(1, 2, 3, 2)).RemoveValue(2).Value();
/// // [1, 3, 2]
///
Функция RemoveValue(Знач Значение) Экспорт
ib = "Удаление первого вхождения значения"; //⚙
Индекс = Данные.Найти(Значение); //✏
Если Индекс <> Неопределено Тогда //⚡
Данные.Удалить(Индекс); //✏
КонецЕсли;
Возврат ЭтотОбъект; //↩
КонецФункции
Функция ConvertTo(Знач TargetType, Знач DefaultValue = Неопределено) Экспорт
Данные = A1sAR.ConvertTo(Данные, TargetType, DefaultValue);
Возврат ЭтотОбъект;
КонецФункции
Функция Reset() Экспорт
Данные = A1sAR.Reset(Данные);
Возврат ЭтотОбъект;
КонецФункции
Функция ResetDeep() Экспорт
Данные = A1sAR.ResetDeep(Данные);
Возврат ЭтотОбъект;
КонецФункции
////////////////////////////////////////////////////////////////////////////////
// ВСТАВКА ДЛЯ A1sDP_AR — Split и PickByType функции
//
// Вставить в #Область ДополнительныеТрансформаторы (после строки 254)
// ИЛИ создать новую #Область ВыборкаПоТипу
////////////////////////////////////////////////////////////////////////////////
#Область РазделениеМассива
/// ✦ Split — Разделить массив по значению (ТЕРМИНАТОР)
/// ➤ Value (Произвольный) — Значение-разделитель
/// ➤ IncludeSeparator (Булево) — Включить разделитель во вторую часть
/// ⬅ Структура — {Before: Массив, After: Массив}
///
/// Пример:
/// Части = A1sAR.On(A1sAR.Of(1,2,3,4,5)).Split(3);
/// // Части.Before = [1,2], Части.After = [4,5]
///
Функция Split(Знач Value, Знач IncludeSeparator = Ложь) Экспорт
ib = "Разделение массива по значению"; //⚙
Возврат A1sAR.Split(Данные, Value, IncludeSeparator); //↩
КонецФункции
/// ✦ SplitAt — Разделить массив по индексу (ТЕРМИНАТОР)
/// ➤ Index (Число) — Индекс разделения
/// ⬅ Структура — {Before: Массив, After: Массив}
///
/// Пример:
/// Части = A1sAR.On(A1sAR.Of(1,2,3,4,5)).SplitAt(2);
/// // Части.Before = [1,2], Части.After = [3,4,5]
///
Функция SplitAt(Знач Index) Экспорт
ib = "Разделение массива по индексу"; //⚙
Возврат A1sAR.SplitAt(Данные, Index); //↩
КонецФункции
#КонецОбласти
#Область ВыборкаПоТипу
/// ✦ PickByType — Оставить только элементы указанного типа (ТРАНСФОРМАТОР)
/// ➤ TypeOrTypes (Тип, Массив, ОписаниеТипов) — Тип или типы для выборки
/// ⬅ A1sDP_AR — ЭтотОбъект для цепочки вызовов
///
/// Пример:
/// Числа = A1sAR.On(Смешанный).PickByType(Тип("Число")).Value();
///
Функция PickByType(Знач TypeOrTypes) Экспорт
ib = "Выборка элементов по типу"; //⚙
Данные = A1sAR.PickByType(Данные, TypeOrTypes); //✏
Возврат ЭтотОбъект; //↩
КонецФункции
/// ✦ OmitByType — Исключить элементы указанного типа (ТРАНСФОРМАТОР)
/// ➤ TypeOrTypes (Тип, Массив, ОписаниеТипов) — Тип или типы для исключения
/// ⬅ A1sDP_AR — ЭтотОбъект для цепочки вызовов
///
Функция OmitByType(Знач TypeOrTypes) Экспорт
ib = "Исключение элементов по типу"; //⚙
Данные = A1sAR.OmitByType(Данные, TypeOrTypes); //✏
Возврат ЭтотОбъект; //↩
КонецФункции
/// ✦ PickRefs — Оставить только ссылки (ТРАНСФОРМАТОР)
/// ⬅ A1sDP_AR — ЭтотОбъект для цепочки вызовов
///
Функция PickRefs() Экспорт
ib = "Выборка только ссылок"; //⚙
Данные = A1sAR.PickRefs(Данные); //✏
Возврат ЭтотОбъект; //↩
КонецФункции
/// ✦ PickFilled — Оставить только заполненные значения (ТРАНСФОРМАТОР)
/// ⬅ A1sDP_AR — ЭтотОбъект для цепочки вызовов
///
Функция PickFilled() Экспорт
ib = "Выборка только заполненных"; //⚙
Данные = A1sAR.PickFilled(Данные); //✏
Возврат ЭтотОбъект; //↩
КонецФункции
/// ✦ PickNotNull — Исключить Неопределено (ТРАНСФОРМАТОР)
/// ⬅ A1sDP_AR — ЭтотОбъект для цепочки вызовов
///
Функция PickNotNull() Экспорт
ib = "Исключение Неопределено"; //⚙
Данные = A1sAR.PickNotNull(Данные); //✏
Возврат ЭтотОбъект; //↩
КонецФункции
/// ✦ GroupByType — Сгруппировать по типу (ТЕРМИНАТОР)
/// ⬅ Соответствие — Ключ = Тип, Значение = Массив элементов
///
/// Пример:
/// Группы = A1sAR.On(Смешанный).GroupByType();
/// // Группы[Тип("Число")] = [1, 2, 3]
/// // Группы[Тип("Строка")] = ["a", "b"]
///
Функция GroupByType() Экспорт
ib = "Группировка по типу"; //⚙
Возврат A1sAR.GroupByType(Данные); //↩
КонецФункции
/// ✦ GetTypes — Оставить в массиве только уникальные типы элементов (ТРАНСФОРМАТОР)
/// ⬅ A1sDP_AR — ЭтотОбъект для цепочки вызовов
///
Функция GetTypes() Экспорт
ib = "A1sDP_AR: Извлечение типов элементов"; //⚙
Данные = A1sAR.GetTypes(Данные); //✏
Возврат ЭтотОбъект; //↩
КонецФункции
#КонецОбласти
/// ✦ Clear — Очистить массив
/// ⬅ A1sDP_AR — ЭтотОбъект для цепочки вызовов
///
/// Пример:
/// A1sAR.On(Старый).Clear().Add(1).Add(2).Value();
///
Функция Clear() Экспорт
ib = "Очистка массива"; //⚙
Данные.Очистить(); //✏
Возврат ЭтотОбъект; //↩
КонецФункции
/// ✦ Filter — Фильтрация элементов по условию
/// ➤ Условие (Строка) — BSL-выражение, где v = текущий элемент
/// ⬅ A1sDP_AR — ЭтотОбъект для цепочки вызовов
///
/// Пример:
/// A1sAR.On(A1sAR.Of(1, 2, 3, 4, 5)).Filter("v > 2").Value();
/// // [3, 4, 5]
///
/// A1sAR.On(Пользователи).Filter("v.Активен").Value();
/// // Только активные
///
Функция Filter(Знач Условие) Экспорт
ib = "Фильтрация элементов по условию"; //⚙
НовыйМассив = Новый Массив; //✏
Для Каждого v Из Данные Цикл //⟳
Попытка
Если Вычислить(Условие) Тогда //⚡
НовыйМассив.Добавить(v); //✏
КонецЕсли;
Исключение
// Пропускаем элементы, вызывающие ошибку в условии
КонецПопытки;
КонецЦикла;
Данные = НовыйМассив; //✏
Возврат ЭтотОбъект; //↩
КонецФункции
/// ✦ Map — Преобразование каждого элемента
/// ➤ Выражение (Строка) — BSL-выражение, где v = текущий элемент
/// ⬅ A1sDP_AR — ЭтотОбъект для цепочки вызовов
///
/// Пример:
/// A1sAR.On(A1sAR.Of(1, 2, 3)).Map("v * 10").Value();
/// // [10, 20, 30]
///
/// A1sAR.On(Пользователи).Map("v.Имя").Value();
/// // ["Иван", "Петр", ...]
///
Функция Map(Знач Выражение) Экспорт
ib = "Преобразование каждого элемента"; //⚙
НовыйМассив = Новый Массив; //✏
Для Каждого v Из Данные Цикл //⟳
Попытка
НовоеЗначение = Вычислить(Выражение); //✏
НовыйМассив.Добавить(НовоеЗначение); //✏
Исключение
НовыйМассив.Добавить(Неопределено); //✏
КонецПопытки;
КонецЦикла;
Данные = НовыйМассив; //✏
Возврат ЭтотОбъект; //↩
КонецФункции
/// ✦ Unique — Удалить дубликаты (алиас для RemoveDuplicates)
/// ⬅ A1sDP_AR — ЭтотОбъект для цепочки вызовов
///
/// Пример:
/// A1sAR.On(A1sAR.Of(1, 2, 2, 3, 3, 3)).Unique().Value();
/// // [1, 2, 3]
///
Функция Unique() Экспорт
ib = "Удаление дубликатов"; //⚙
Возврат RemoveDuplicates(); //↩
КонецФункции
/// ✦ Slice — Вырезать часть массива
/// ➤ Начало (Число) — Начальный индекс (с 0)
/// ➤ Конец (Число, Неопределено) — Конечный индекс (не включая), или до конца
/// ⬅ A1sDP_AR — ЭтотОбъект для цепочки вызовов
///
/// Пример:
/// A1sAR.On(A1sAR.Of(0, 1, 2, 3, 4, 5)).Slice(2, 5).Value();
/// // [2, 3, 4]
///
Функция Slice(Знач Начало, Знач Конец = Неопределено) Экспорт
ib = "Вырезание части массива"; //⚙
Если Конец = Неопределено Тогда //⚡
Конец = Данные.Количество(); //✏
КонецЕсли;
НовыйМассив = Новый Массив; //✏
Для Индекс = Начало По Мин(Конец - 1, Данные.Количество() - 1) Цикл //⟳
Если Индекс >= 0 И Индекс < Данные.Количество() Тогда //⚡
НовыйМассив.Добавить(Данные[Индекс]); //✏
КонецЕсли;
КонецЦикла;
Данные = НовыйМассив; //✏
Возврат ЭтотОбъект; //↩
КонецФункции
/// ✦ Take — Взять первые N элементов
/// ➤ Количество (Число) — Сколько элементов взять
/// ⬅ A1sDP_AR — ЭтотОбъект для цепочки вызовов
///
/// Пример:
/// A1sAR.On(A1sAR.Of(1, 2, 3, 4, 5)).Take(3).Value();
/// // [1, 2, 3]
///
Функция Take(Знач Количество) Экспорт
ib = "Взятие первых N элементов"; //⚙
Возврат Slice(0, Количество); //↩
КонецФункции
/// ✦ Skip — Пропустить первые N элементов
/// ➤ Количество (Число) — Сколько элементов пропустить
/// ⬅ A1sDP_AR — ЭтотОбъект для цепочки вызовов
///
/// Пример:
/// A1sAR.On(A1sAR.Of(1, 2, 3, 4, 5)).Skip(2).Value();
/// // [3, 4, 5]
///
Функция Skip(Знач Количество) Экспорт
ib = "Пропуск первых N элементов"; //⚙
Возврат Slice(Количество); //↩
КонецФункции
/// ✦ Flatten — Развернуть вложенные массивы (один уровень)
/// ⬅ A1sDP_AR — ЭтотОбъект для цепочки вызовов
///
/// Пример:
/// A1sAR.On(A1sAR.Of(A1sAR.Of(1, 2), A1sAR.Of(3, 4))).Flatten().Value();
/// // [1, 2, 3, 4]
///
Функция Flatten() Экспорт
ib = "Разворачивание вложенных массивов"; //⚙
НовыйМассив = Новый Массив; //✏
Для Каждого Элемент Из Данные Цикл //⟳
Если ТипЗнч(Элемент) = Тип("Массив") ИЛИ ТипЗнч(Элемент) = Тип("ФиксированныйМассив") Тогда //⚡
Для Каждого Вложенный Из Элемент Цикл //⟳
НовыйМассив.Добавить(Вложенный); //✏
КонецЦикла;
Иначе
НовыйМассив.Добавить(Элемент); //✏
КонецЕсли;
КонецЦикла;
Данные = НовыйМассив; //✏
Возврат ЭтотОбъект; //↩
КонецФункции
#КонецОбласти
#Область ДополнительныеТерминаторы
/// ✦ ToFixed — Получить фиксированный массив
/// ⬅ ФиксированныйМассив — Неизменяемый массив
///
/// Пример:
/// Константы = A1sAR.On().Add("Пн").Add("Вт").Add("Ср").ToFixed();
///
Функция ToFixed() Экспорт
ib = "Получение фиксированного массива"; //⚙
Возврат Новый ФиксированныйМассив(Данные); //↩
КонецФункции
/// ✦ Get — Получить элемент по индексу с умолчанием
/// ➤ Индекс (Число) — Индекс элемента (с 0)
/// ➤ Умолчание (Произвольный) — Значение если индекс вне границ
/// ⬅ Произвольный — Элемент или умолчание
///
/// Пример:
/// Третий = A1sAR.On(Массив).Get(2, "не найдено");
///
Функция Get(Знач Индекс, Знач Умолчание = Неопределено) Экспорт
ib = "Получение элемента по индексу"; //⚙
Если Индекс >= 0 И Индекс < Данные.Количество() Тогда //⚡
Возврат Данные[Индекс]; //↩
Иначе
Возврат Умолчание; //↩
КонецЕсли;
КонецФункции
/// ✦ Total — Сумма числовых элементов
/// ⬅ Число — Сумма
///
/// Пример:
/// Итого = A1sAR.On(A1sAR.Of(10, 20, 30)).Total();
/// // 60
///
Функция Total() Экспорт
ib = "Сумма элементов массива"; //⚙
Результат = 0; //✏
Для Каждого Элемент Из Данные Цикл //⟳
Если ТипЗнч(Элемент) = Тип("Число") Тогда //⚡
Результат = Результат + Элемент; //✏
КонецЕсли;
КонецЦикла;
Возврат Результат; //↩
КонецФункции
/// ✦ Minimum — Минимальное значение
/// ⬅ Произвольный — Минимальный элемент или Неопределено
///
/// Пример:
/// Минимум = A1sAR.On(A1sAR.Of(5, 2, 8, 1, 9)).Minimum();
/// // 1
///
Функция Minimum() Экспорт
ib = "Минимальный элемент массива"; //⚙
Если Данные.Количество() = 0 Тогда //⚡
Возврат Неопределено; //↩
КонецЕсли;
Результат = Данные[0]; //✏
Для Индекс = 1 По Данные.Количество() - 1 Цикл //⟳
Если Данные[Индекс] < Результат Тогда //⚡
Результат = Данные[Индекс]; //✏
КонецЕсли;
КонецЦикла;
Возврат Результат; //↩
КонецФункции
/// ✦ Maximum — Максимальное значение
/// ⬅ Произвольный — Максимальный элемент или Неопределено
///
/// Пример:
/// Максимум = A1sAR.On(A1sAR.Of(5, 2, 8, 1, 9)).Maximum();
/// // 9
///
Функция Maximum() Экспорт
ib = "Максимальный элемент массива"; //⚙
Если Данные.Количество() = 0 Тогда //⚡
Возврат Неопределено; //↩
КонецЕсли;
Результат = Данные[0]; //✏
Для Индекс = 1 По Данные.Количество() - 1 Цикл //⟳
Если Данные[Индекс] > Результат Тогда //⚡
Результат = Данные[Индекс]; //✏
КонецЕсли;
КонецЦикла;
Возврат Результат; //↩
КонецФункции
/// ✦ Avg — Среднее арифметическое
/// ⬅ Число — Среднее или 0 если массив пуст
///
/// Пример:
/// Среднее = A1sAR.On(A1sAR.Of(10, 20, 30)).Avg();
/// // 20
///
Функция Avg() Экспорт
ib = "Среднее арифметическое"; //⚙
Если Данные.Количество() = 0 Тогда //⚡
Возврат 0; //↩
КонецЕсли;
Возврат Total() / Данные.Количество(); //↩
КонецФункции
/// ✦ Reduce — Свёртка массива
/// ➤ Выражение (Строка) — BSL-выражение, где acc = аккумулятор, v = элемент
/// ➤ Начальное (Произвольный) — Начальное значение аккумулятора
/// ⬅ Произвольный — Результат свёртки
///
/// Пример:
/// Сумма = A1sAR.On(A1sAR.Of(1, 2, 3, 4)).Reduce("acc + v", 0);
/// // 10
///
/// Произведение = A1sAR.On(A1sAR.Of(1, 2, 3, 4)).Reduce("acc * v", 1);
/// // 24
///
Функция Reduce(Знач Выражение, Знач Начальное) Экспорт
ib = "Свёртка массива"; //⚙
acc = Начальное; //✏
Для Каждого v Из Данные Цикл //⟳
Попытка
acc = Вычислить(Выражение); //✏
Исключение
// Пропускаем ошибки
КонецПопытки;
КонецЦикла;
Возврат acc; //↩
КонецФункции
/// ✦ IsHomoTyped — Проверить на однородность типов (ТЕРМИНАТОР)
/// ⬅ Булево — Истина, если все элементы одного типа
///
Функция IsHomoTyped() Экспорт
ib = "A1sDP_AR: Проверка на однородность"; //⚙
Возврат A1sAR.IsHomoTyped(Данные); //↩
КонецФункции
/// ✦ MostFrequentType — Найти самый частый тип (ТЕРМИНАТОР)
/// ⬅ Тип — Доминирующий тип данных в массиве
///
Функция MostFrequentType() Экспорт
ib = "A1sDP_AR: Определение доминирующего типа"; //⚙
Возврат A1sAR.MostFrequentType(Данные); //↩
КонецФункции
#КонецОбласти
#Область SelfTest
/// ✦ SelfTest — Самотестирование обработки A1sDP_AR
/// ⬅ Булево — Истина если все тесты пройдены
///
Функция SelfTest() Экспорт
ib = "Запуск самотестирования"; //⚙
Успешно = Истина; //✏
ВсегоТестов = 0; //✏
ПройденоТестов = 0; //✏
// ═══════════════════════════════════════════════════════════════
// ТЕСТ 1: Add + Value
// ═══════════════════════════════════════════════════════════════
ВсегоТестов = ВсегоТестов + 1; //✏
Попытка
УстановитьДанные(Новый Массив); //▶️
Результат = Add(1).Add(2).Add(3).Value(); //▶️
Если Результат.Количество() = 3 И Результат[0] = 1 И Результат[2] = 3 Тогда //⚡
ПройденоТестов = ПройденоТестов + 1; //✏
Иначе
Сообщить("A1sDP_AR.SelfTest: Тест 1 не пройден"); //▶️
Успешно = Ложь; //✏
КонецЕсли;
Исключение
Сообщить("A1sDP_AR.SelfTest: Тест 1 — исключение: " + ОписаниеОшибки()); //▶️
Успешно = Ложь; //✏
КонецПопытки;
// ═══════════════════════════════════════════════════════════════
// ТЕСТ 2: Filter
// ═══════════════════════════════════════════════════════════════
ВсегоТестов = ВсегоТестов + 1; //✏
Попытка
Исходный = Новый Массив; //✏
Исходный.Добавить(1); Исходный.Добавить(2); Исходный.Добавить(3);
Исходный.Добавить(4); Исходный.Добавить(5); //✏
УстановитьДанные(Исходный); //▶️
Результат = Filter("v > 2").Value(); //▶️
Если Результат.Количество() = 3 И Результат[0] = 3 И Результат[2] = 5 Тогда //⚡
ПройденоТестов = ПройденоТестов + 1; //✏
Иначе
Сообщить("A1sDP_AR.SelfTest: Тест 2 не пройден — Filter неверно"); //▶️
Успешно = Ложь; //✏
КонецЕсли;
Исключение
Сообщить("A1sDP_AR.SelfTest: Тест 2 — исключение: " + ОписаниеОшибки()); //▶️
Успешно = Ложь; //✏
КонецПопытки;
// ═══════════════════════════════════════════════════════════════
// ТЕСТ 3: Map
// ═══════════════════════════════════════════════════════════════
ВсегоТестов = ВсегоТестов + 1; //✏
Попытка
Исходный = Новый Массив; //✏
Исходный.Добавить(1); Исходный.Добавить(2); Исходный.Добавить(3); //✏
УстановитьДанные(Исходный); //▶️
Результат = Map("v * 10").Value(); //▶️
Если Результат.Количество() = 3 И Результат[0] = 10 И Результат[2] = 30 Тогда //⚡
ПройденоТестов = ПройденоТестов + 1; //✏
Иначе
Сообщить("A1sDP_AR.SelfTest: Тест 3 не пройден — Map неверно"); //▶️
Успешно = Ложь; //✏
КонецЕсли;
Исключение
Сообщить("A1sDP_AR.SelfTest: Тест 3 — исключение: " + ОписаниеОшибки()); //▶️
Успешно = Ложь; //✏
КонецПопытки;
// ═══════════════════════════════════════════════════════════════
// ТЕСТ 4: Take + Skip
// ═══════════════════════════════════════════════════════════════
ВсегоТестов = ВсегоТестов + 1; //✏
Попытка
Исходный = Новый Массив; //✏
Для i = 1 По 10 Цикл Исходный.Добавить(i); КонецЦикла; //⟳
УстановитьДанные(Исходный); //▶️
Результат = Skip(3).Take(4).Value(); //▶️
// Должно быть [4, 5, 6, 7]
Если Результат.Количество() = 4 И Результат[0] = 4 И Результат[3] = 7 Тогда //⚡
ПройденоТестов = ПройденоТестов + 1; //✏
Иначе
Сообщить("A1sDP_AR.SelfTest: Тест 4 не пройден — Take/Skip неверно"); //▶️
Успешно = Ложь; //✏
КонецЕсли;
Исключение
Сообщить("A1sDP_AR.SelfTest: Тест 4 — исключение: " + ОписаниеОшибки()); //▶️
Успешно = Ложь; //✏
КонецПопытки;
// ═══════════════════════════════════════════════════════════════
// ТЕСТ 5: Sum, Min, Max, Avg
// ═══════════════════════════════════════════════════════════════
ВсегоТестов = ВсегоТестов + 1; //✏
Попытка
Исходный = Новый Массив; //✏
Исходный.Добавить(10); Исходный.Добавить(20); Исходный.Добавить(30); //✏
УстановитьДанные(Исходный); //▶️
Если Total() = 60 И Minimum() = 10 И Maximum() = 30 И Avg() = 20 Тогда //⚡
ПройденоТестов = ПройденоТестов + 1; //✏
Иначе
Сообщить("A1sDP_AR.SelfTest: Тест 5 не пройден — агрегация неверна"); //▶️
Успешно = Ложь; //✏
КонецЕсли;
Исключение
Сообщить("A1sDP_AR.SelfTest: Тест 5 — исключение: " + ОписаниеОшибки()); //▶️
Успешно = Ложь; //✏
КонецПопытки;
// ═══════════════════════════════════════════════════════════════
// ТЕСТ 6: Reduce
// ═══════════════════════════════════════════════════════════════
ВсегоТестов = ВсегоТестов + 1; //✏
Попытка
Исходный = Новый Массив; //✏
Исходный.Добавить(1); Исходный.Добавить(2); Исходный.Добавить(3); Исходный.Добавить(4); //✏
УстановитьДанные(Исходный); //▶️
РезультатСумма = Reduce("acc + v", 0); //▶️
УстановитьДанные(Исходный); //▶️
РезультатПроизв = Reduce("acc * v", 1); //▶️
Если РезультатСумма = 10 И РезультатПроизв = 24 Тогда //⚡
ПройденоТестов = ПройденоТестов + 1; //✏
Иначе
Сообщить("A1sDP_AR.SelfTest: Тест 6 не пройден — Reduce неверно"); //▶️
Успешно = Ложь; //✏
КонецЕсли;
Исключение
Сообщить("A1sDP_AR.SelfTest: Тест 6 — исключение: " + ОписаниеОшибки()); //▶️
Успешно = Ложь; //✏
КонецПопытки;
// ═══════════════════════════════════════════════════════════════
// ТЕСТ 7: Flatten
// ═══════════════════════════════════════════════════════════════
ВсегоТестов = ВсегоТестов + 1; //✏
Попытка
Вложенный1 = Новый Массив; Вложенный1.Добавить(1); Вложенный1.Добавить(2); //✏
Вложенный2 = Новый Массив; Вложенный2.Добавить(3); Вложенный2.Добавить(4); //✏
Исходный = Новый Массив; //✏
Исходный.Добавить(Вложенный1); //✏
Исходный.Добавить(Вложенный2); //✏
УстановитьДанные(Исходный); //▶️
Результат = Flatten().Value(); //▶️
Если Результат.Количество() = 4 И Результат[0] = 1 И Результат[3] = 4 Тогда //⚡
ПройденоТестов = ПройденоТестов + 1; //✏
Иначе
Сообщить("A1sDP_AR.SelfTest: Тест 7 не пройден — Flatten неверно"); //▶️
Успешно = Ложь; //✏
КонецЕсли;
Исключение
Сообщить("A1sDP_AR.SelfTest: Тест 7 — исключение: " + ОписаниеОшибки()); //▶️
Успешно = Ложь; //✏
КонецПопытки;
// ═══════════════════════════════════════════════════════════════
// ТЕСТ 8: Комплексная цепочка
// ═══════════════════════════════════════════════════════════════
ВсегоТестов = ВсегоТестов + 1; //✏
Попытка
Исходный = Новый Массив; //✏
Для i = 1 По 10 Цикл Исходный.Добавить(i); КонецЦикла; //⟳
УстановитьДанные(Исходный); //▶️
// Взять числа > 3, умножить на 10, взять первые 3
Результат = Filter("v > 3").Map("v * 10").Take(3).Value(); //▶️
// Должно быть [40, 50, 60]
Если Результат.Количество() = 3 И Результат[0] = 40 И Результат[2] = 60 Тогда //⚡
ПройденоТестов = ПройденоТестов + 1; //✏
Иначе
Сообщить("A1sDP_AR.SelfTest: Тест 8 не пройден — цепочка неверна"); //▶️
Успешно = Ложь; //✏
КонецЕсли;
Исключение
Сообщить("A1sDP_AR.SelfTest: Тест 8 — исключение: " + ОписаниеОшибки()); //▶️
Успешно = Ложь; //✏
КонецПопытки;
// ═══════════════════════════════════════════════════════════════
// ТЕСТ 9: Функции типизации (GetTypes, IsHomo, MostFrequent)
// ═══════════════════════════════════════════════════════════════
ВсегоТестов = ВсегоТестов + 1; //✏
Попытка
// Создаем гетерогенный массив: 2 числа и 1 строка
УстановитьДанные(A1sAR.Of(10, 20, "Текст")); //▶️
Гетер = Not IsHomoTyped(); // Должно быть Истина
ЧастыйТип = MostFrequentType(); // Должно быть Тип("Число")
// Оставляем только числа через цепочку
Результат = PickByType(Тип("Число")).Value();
Если Гетер = Истина И ЧастыйТип = Тип("Число") И Результат.Количество() = 2 Тогда //⚡
ПройденоТестов = ПройденоТестов + 1; //✏
Иначе
Сообщить("A1sDP_AR.SelfTest: Тест 9 не пройден — Типизация"); //▶️
Успешно = Ложь; //✏
КонецЕсли;
Исключение
Сообщить("A1sDP_AR.SelfTest: Тест 9 — исключение: " + ОписаниеОшибки()); //▶️
Успешно = Ложь; //✏
КонецПопытки;
// ═══════════════════════════════════════════════════════════════
// ИТОГИ
// ═══════════════════════════════════════════════════════════════
Если Успешно Тогда //⚡
Сообщить("✓ A1sDP_AR.SelfTest: Пройдено " + Строка(ПройденоТестов) + " из " + Строка(ВсегоТестов) + " тестов"); //▶️
Иначе
Сообщить("✗ A1sDP_AR.SelfTest: ОШИБКА! Пройдено " + Строка(ПройденоТестов) + " из " + Строка(ВсегоТестов) + " тестов"); //▶️
КонецЕсли;
Возврат Успешно; //↩
КонецФункции
#КонецОбласти
#Область СериализацияИСанация
/// ✦ Sanitize — Очистить массив (Безопасный режим)
&AtServer
Функция Sanitize() Экспорт
// Очищаем через ядро A1sDS
Данные = A1sDS.Sanitize(Данные);
Возврат ЭтотОбъект;
КонецФункции
/// ✦ ToJSON — Получить JSON (Безопасный режим)
///
/// В отличие от статического A1sAR.ToJSON, этот метод СТАНДАРТНО вызывает Sanitize.
/// Это предотвращает падения и делает цепочку .On().ToJSON() удобной.
///
&AtServer
Функция ToJSON() Экспорт
// ✅ SAFE MODE:
// Мы гарантируем безопасность, поэтому явно вызываем Sanitize перед вызовом Strict A1sAR.
// Это может вызвать Double Sanitize, если пользователь сам написал .Sanitize() выше в цепочке,
// но это цена удобства флоуент-интерфейса.
ЧистыеДанные = A1sAR.Sanitize(Данные);
Возврат A1sAR.ToJSON(ЧистыеДанные);
КонецФункции
#КонецОбласти
#Область Инициализация
Данные = Новый Массив; //✏
#КонецОбласти