Как получить уникальные значения массива в 1С?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

Часто в процессе разработки возникает задача уникализации данных в коллекции Массив. У этой универсальной коллекции в 1С нет встроенных методов для автоматической уникализации, таких как метод Свернуть(), который доступен для таблицы значений. Рассмотрим подробнее, почему возникают ошибки при попытке очистить массив от дублей "на месте", и разберем несколько проверенных способов решения этой задачи.

Почему нельзя удалять элементы массива в прямом цикле?

Проанализируем частую ошибку начинающих разработчиков — попытку удалить дубликаты, перебирая массив с помощью цикла Для Каждого или прямого цикла по индексам Для Индекс = 0 По Количество - 1. Главная проблема кроется в том, что при удалении любого элемента из коллекции происходит неявное смещение индексов: все элементы, расположенные правее удаленного, сдвигаются на одну позицию влево, чтобы заполнить пустоту.

Так как итератор цикла при этом продолжает двигаться вперед, элемент, вставший на место удаленного, пропускается и вообще не обрабатывается алгоритмом. Кроме того, прямое удаление при обходе оператором Для Каждого часто приводит к непредсказуемым результатам или ошибкам выхода за границы коллекции. Выясним, как сделать это правильно, если стоит жесткое условие не создавать новые коллекции.

Решение 1: Удаление дублей "на месте" (Обратный обход)

Если необходимо модифицировать исходный массив без создания дополнительных структур данных, единственным корректным алгоритмом является обратный обход массива — от конца к началу. Посмотрим на логику такого обхода по шагам:

  1. Задаем стартовый индекс, равный верхней границе массива.
  2. Запускаем цикл, который будет двигаться к нулю.
  3. Берем элемент по текущему индексу и проверяем, есть ли такое же значение левее текущей позиции.
  4. Если дубль найден, удаляем элемент. Поскольку удаляется элемент в "хвосте", индексы элементов в начале массива не смещаются, и мы ничего не пропускаем.

Пример реализации алгоритма:


Индекс = Массив.ВГраница();
Пока Индекс >= 0 Цикл
    ТекущееЗначение = Массив[Индекс];
    ИндексПервогоВхождения = Массив.Найти(ТекущееЗначение);
    
    // Если элемент найден ближе к началу массива, значит текущий элемент — это дубль
    Если ИндексПервогоВхождения < Индекс Тогда
        Массив.Удалить(Индекс);
    КонецЕсли;
    
    Индекс = Индекс - 1;
КонецЦикла;

Решение 2: Использование коллекции "Соответствие"

Разберем гораздо более простой и быстрый способ уникализации, если создание новых коллекций допустимо. Объект Соответствие устроен таким образом, что ключи в нем всегда уникальны. Мы можем использовать значения массива в качестве ключей соответствия, а затем выгрузить эти ключи обратно в новый массив.


Функция СвернутьМассив(пМассив)
    Уник = Новый Соответствие;
    
    Для Каждого Значение Из пМассив Цикл
        Уник.Вставить(Значение, Истина);
    КонецЦикла;
    
    Рез = Новый Массив;
    Для Каждого КлючЗначение Из Уник Цикл
        Рез.Добавить(КлючЗначение.Ключ);
    КонецЦикла;
    
    Возврат Рез;
КонецФункции

Решение 3: Использование Таблицы Значений

Еще один классический вариант — задействовать объект ТаблицаЗначений. У него есть встроенный метод Свернуть(). Этот способ отлично подходит, если в дальнейшем уникализированные данные удобнее обрабатывать именно в виде таблицы.


Табло = Новый ТаблицаЗначений;
Табло.Колонки.Добавить("НашПараметр");
// Загружаем наш массив в единственную колонку таблицы
Табло.ЗагрузитьКолонку(ПараметрыЗапроса, "НашПараметр");
// Сворачиваем таблицу по этой колонке
Табло.Свернуть("НашПараметр", "");
// Если нужен обратно массив, можно использовать:
// МассивУникальных = Табло.ВыгрузитьКолонку("НашПараметр");

Решение 4: Стандартные функции БСП

Если в вашей конфигурации внедрена Библиотека Стандартных Подсистем (БСП), нет необходимости изобретать велосипед. Разработчики 1С уже предусмотрели готовую функцию для этой задачи. Просто используйте метод общего модуля:

ОбщегоНазначенияКлиентСервер.СвернутьМассив(ВашМассивСДублями);

Эта функция самостоятельно удалит все дубликаты, оставив в переданном массиве только уникальные значения. Применение стандартизированных функций БСП всегда предпочтительнее, так как это делает код более читаемым и сокращает время на разработку.

← На главную