Идея дня
- Избегаем «мутаций» исходных массивов — возвращаем новые массивы из утилит.
- Всегда проверяем границы индексов: <0 → 0; >Количество → конец.
- Срезы и вставки собираем через копирование элементов в новый массив.
Вспомогательные утилиты
Функция ArrayClone(A) Экспорт
Рез = Новый Массив;
Если A1sO.Empty(A) Тогда Возврат Рез; КонецЕсли;
Для каждого V Из A Цикл Рез.Добавить(V); КонецЦикла;
Возврат Рез;
КонецФункции
Функция _Clamp(Значение, МинЗн, МаксЗн) Экспорт
Если Значение < МинЗн Тогда Возврат МинЗн; КонецЕсли;
Если Значение > МаксЗн Тогда Возврат МаксЗн; КонецЕсли;
Возврат Значение;
КонецФункции
Вставка по индексу (InsertAt)
Функция ArrayInsertAt(A, Индекс, Значение) Экспорт
Рез = ArrayClone(A);
Кол = Рез.Количество();
Позиция = _Clamp(A1sO.NumOrZero(Индекс), 0, Кол); // допускаем вставку в конец
Рез.Вставить(Значение, Позиция);
Возврат Рез;
КонецФункции
// Пример
A = Новый Массив; A.Добавить("A"); A.Добавить("B"); A.Добавить("C");
B = ArrayInsertAt(A, 1, "X"); // ["A","X","B","C"], A не изменился
Удаление по индексу (RemoveAt)
Функция ArrayRemoveAt(A, Индекс) Экспорт
Если A1sO.Empty(A) Тогда Возврат Новый Массив; КонецЕсли;
Рез = ArrayClone(A);
Кол = Рез.Количество();
Если Индекс < 0 Или Индекс >= Кол Тогда Возврат Рез; КонецЕсли;
Рез.Удалить(Индекс); // удаление по индексу
Возврат Рез;
КонецФункции
// Пример
B = ArrayRemoveAt(B, 2); // ["A","X","C"]
Удаление по значению (RemoveWhereEquals)
Функция ArrayRemoveWhereEquals(A, Значение, УдалитьВсе = Истина) Экспорт
Если A1sO.Empty(A) Тогда Возврат Новый Массив; КонецЕсли;
Рез = ArrayClone(A);
// Идём с конца, чтобы индексы не «плыли»
Для И = Рез.Количество()-1 По 0 Шаг -1 Цикл
Если Рез[И] = Значение Тогда
Рез.Удалить(И);
Если НЕ УдалитьВсе Тогда Прервать; КонецЕсли;
КонецЕсли;
КонецЦикла;
Возврат Рез;
КонецФункции
// Пример
C = ArrayRemoveWhereEquals(Новый Массив("A","B","X","B","C"), "B"); // ["A","X","C"]
Срез (Slice)
Функция ArraySlice(A, Начало, КоличествоЭл = Неопределено) Экспорт
Рез = Новый Массив;
Если A1sO.Empty(A) Тогда Возврат Рез; КонецЕсли;
N = A1sO.NumOrZero(Начало);
Если N < 0 Тогда N = 0; КонецЕсли;
Всего = A.Количество();
Кон = ?(КоличествоЭл = Неопределено, Всего, N + A1sO.NumOrZero(КоличествоЭл));
Если Кон > Всего Тогда Кон = Всего; КонецЕсли;
Для И = N По Кон-1 Цикл
Рез.Добавить(A[И]);
КонецЦикла;
Возврат Рез;
КонецФункции
// Примеры
Slice1 = ArraySlice(Новый Массив("A","B","C","D"), 1, 2); // ["B","C"]
Slice2 = ArraySlice(Новый Массив("A","B","C","D"), 2); // ["C","D"]
Обновление по индексу (UpdateAt)
Функция ArrayUpdateAt(A, Индекс, НовоеЗначение) Экспорт
Если A1sO.Empty(A) Тогда Возврат Новый Массив; КонецЕсли;
Рез = ArrayClone(A);
Если Индекс < 0 Или Индекс >= Рез.Количество() Тогда Возврат Рез; КонецЕсли;
Рез[Индекс] = НовоеЗначение;
Возврат Рез;
КонецФункции
// Пример
Upd = ArrayUpdateAt(Новый Массив("A","X","C"), 0, "AA"); // ["AA","X","C"]
Обновление по условию (UpdateWhere...)
Без «функций-колбэков» используем типовые предикаты.
Заменить строку, содержащую подстроку
Функция ArrayUpdateWhereContains(МассивСтрок, Подстрока, НовоеЗначение) Экспорт
Рез = Новый Массив;
Ищем = ВРег(A1sS.AsString(Подстрока));
Для каждого S Из МассивСтрок Цикл
Если СтрНайти(ВРег(A1sS.AsString(S)), Ищем) > 0 Тогда
Рез.Добавить(НовоеЗначение);
Иначе
Рез.Добавить(S);
КонецЕсли;
КонецЦикла;
Возврат Рез;
КонецФункции
R = ArrayUpdateWhereContains(Новый Массив("Кабель ПВС","Вилка","Кабель ВВГ"), "кабель", "[CABLE]");
/* ["[CABLE]","Вилка","[CABLE]"] */
Структуры: обновить поле где Код = ...
Функция ArrayUpdateWhereFieldEquals(МассивСтруктур, ИмяПоля, ИскомоеЗнач, ИмяПоляДляОбновл, НовоеЗнач) Экспорт
Рез = Новый Массив;
Для каждого Э Из МассивСтруктур Цикл
Коп = Новый Структура; // делаем независимую копию элемента
Для каждого П Из Э Цикл Коп.Вставить(П.Ключ, П.Значение); КонецЦикла;
Если Коп.Свойство(ИмяПоля) И Коп[ИмяПоля] = ИскомоеЗнач Тогда
Коп.Вставить(ИмяПоляДляОбновл, НовоеЗнач);
КонецЕсли;
Рез.Добавить(Коп);
КонецЦикла;
Возврат Рез;
КонецФункции
// Пример
Позиции = Новый Массив;
Позиции.Добавить(Новый Структура("Код,Наименование,Цена", "A1", "Кабель ПВС", 199.9));
Позиции.Добавить(Новый Структура("Код,Наименование,Цена", "B2", "Розетка", 150));
Обновл = ArrayUpdateWhereFieldEquals(Позиции, "Код", "A1", "Цена", 189.9);
Пример конвейера: из A1sQ → правки → для UI
Таб = A1sQ.Unload("
|ВЫБРАТЬ ПЕРВЫЕ &Лимит
| Ном.Наименование КАК Name
|ИЗ Справочник.Номенклатура КАК Ном
|УПОРЯДОЧИТЬ ПО Name
", 8);
Имена = Таб.ВыгрузитьКолонку("Name");
// 1) Вставим «— ВСЕ —» в начало
Имена = ArrayInsertAt(Имена, 0, "— ВСЕ —");
// 2) Удалим 4-й элемент (индекс 3), если есть
Имена = ArrayRemoveAt(Имена, 3);
// 3) Срез первых 5
Первые5 = ArraySlice(Имена, 0, 5);
// 4) Пометим все, что содержит "кабель"
Лейблы = ArrayUpdateWhereContains(Первые5, "кабель", "[CABLE]");
Анти-паттерны
- Менять исходный массив «на месте» и переиспользовать его в разных местах — получите неочевидные эффекты.
- Не проверять индексы — выход за границы даёт ошибки или странные результаты.
- Смешивать управление элементами и сортировку/уникальность — держите это отдельными шагами (см. День 27).
Практика (15–30 минут)
- Реализуйте
ArrayInsertAt/ArrayRemoveAtи покройте крайние случаи индексов. - Сделайте
ArraySliceи подтвердите, что исходный массив не меняется. - Добавьте
ArrayUpdateWhereContainsиArrayUpdateWhereFieldEqualsдля ваших кейсов. - Соберите конвейер «выгрузка → правки → вывод в UI».
Что дальше
День 27: A1sArrays — Сортировка и уникальность — сравнение строк/чисел, компараторы, кейсы «без дублей».
Примечание
Код и тексты на этой странице сгенерированы ИИ. Возможны неточности и ошибки. Перед использованием проверяйте и адаптируйте примеры под вашу версию платформы 1С и сборку библиотеки A1sCode.