К статье
Практический материал

Разработка и Конфигурация · 9 мин

Как удалить дубликаты в массиве 1С

Как удалить дубликаты в массиве 1С: перебор с проверкой, свёртка через Соответствие, ТаблицаЗначений и СписокЗначений. Примеры кода, ошибки и проверка результата.

Массив в 1С не имеет встроенного метода удаления дубликатов, поэтому задачу решают вручную: перебором элементов с проверкой вхождения или через вспомогательные коллекции — Соответствие, ТаблицаЗначений, СписокЗначений. Выбор способа зависит от объёма данных, необходимости сохранить порядок элементов и требований к производительности.

Ниже разобраны четыре рабочих подхода с готовым кодом на встроенном языке 1С, их ограничения, типичные ошибки и способы проверить результат. Все примеры применимы как в толстом и тонком клиенте, так и на сервере.

Почему в массиве 1С появляются дубликаты и какой способ выбрать

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

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

Также заранее решите, важен ли порядок элементов. Перебор с проверкой сохраняет исходный порядок первых вхождений. Соответствие порядок не гарантирует, а свёртка таблицы значений сортирует или группирует данные в зависимости от настроек.

Маршрут решения

Как выбрать способ

Массив небольшой (до нескольких сотен элементов) и важен порядокИспользуйте перебор с проверкой через Найти()
Массив большой, порядок не важенИспользуйте Соответствие: ключи уникальны по определению
Нужна дополнительная обработка (подсчёт, сортировка)Выгрузите массив в ТаблицуЗначений и выполните Свернуть()
Массив состоит из простых значений и нужен интерактивный контрольПодойдёт СписокЗначений с проверкой НайтиПоЗначению()

Способ 1. Перебор массива с проверкой через Найти()

Самый наглядный метод: создаётся новый массив, в который элемент добавляется только если его там ещё нет. Порядок первых вхождений сохраняется, код легко читается и отлаживается.

Функция УдалитьДубликаты(ИсходныйМассив)

Результат = Новый Массив;

Для Каждого Элемент Из ИсходныйМассив Цикл

Если Результат.Найти(Элемент) = Неопределено Тогда

Результат.Добавить(Элемент);

КонецЕсли;

КонецЦикла;

Возврат Результат;

КонецФункции

Метод Найти() возвращает индекс найденного элемента или Неопределено, если элемента нет. Именно проверка на Неопределено отсекает повторные добавления.

Ограничение способа — производительность. Каждый вызов Найти() линейно проходит по результирующему массиву, поэтому на массивах в десятки тысяч элементов время выполнения заметно растёт. Для таких объёмов переходите к Соответствию.

Способ 2. Удаление дубликатов через Соответствие

Соответствие — коллекция «ключ-значение», где ключ всегда уникален. Если использовать элементы массива как ключи, дубликаты исчезнут автоматически: повторная установка того же ключа просто перезапишет значение.

Функция УдалитьДубликатыСоответствием(ИсходныйМассив)

Уникальные = Новый Соответствие;

Для Каждого Элемент Из ИсходныйМассив Цикл

Уникальные.Вставить(Элемент, Истина);

КонецЦикла;

Результат = Новый Массив;

Для Каждого Пара Из Уникальные Цикл

Результат.Добавить(Пара.Ключ);

КонецЦикла;

Возврат Результат;

КонецФункции

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

Минус — порядок обхода Соответствия не совпадает с порядком добавления. Если дальше по логике требуется исходная последовательность элементов, комбинируйте подходы: проверяйте вхождение через Соответствие, а добавляйте в результирующий массив в исходном порядке.

1c
Уникальные = Новый Соответствие;
Результат = Новый Массив;
Для Каждого Элемент Из ИсходныйМассив Цикл
	Если Уникальные[Элемент] = Неопределено Тогда
		Уникальные.Вставить(Элемент, Истина);
		Результат.Добавить(Элемент);
	КонецЕсли;
КонецЦикла;

Способ 3. Свёртка через ТаблицуЗначений

ТаблицаЗначений имеет встроенный метод Свернуть(), который группирует строки по указанным колонкам и убирает повторы. Массив выгружается в колонку таблицы, выполняется свёртка, затем результат выгружается обратно в массив.

Таблица = Новый ТаблицаЗначений;

Таблица.Колонки.Добавить("Значение");

Для Каждого Элемент Из ИсходныйМассив Цикл

Таблица.Добавить().Значение = Элемент;

КонецЦикла;

Таблица.Свернуть("Значение");

Результат = Таблица.ВыгрузитьКолонку("Значение");

Способ удобен, когда помимо удаления дубликатов нужно что-то ещё: отсортировать значения, посчитать количество вхождений каждого элемента (через добавление колонки-счётчика и суммирование при свёртке) или отфильтровать результат. Одна структура данных закрывает сразу несколько задач.

Учтите, что при объявлении колонки без явного типа в неё можно поместить значения разных типов, но для стабильной свёртки лучше задать тип через ОписаниеТипов, если массив однородный. Порядок строк после свёртки определяется платформой и не гарантирует совпадения с исходным массивом.

Способ 4. СписокЗначений и особые случаи

СписокЗначений подходит, когда элементы — простые значения или ссылки и требуется метод НайтиПоЗначению(). Логика та же, что у перебора массива: элемент добавляется, только если его ещё нет в списке.

Список = Новый СписокЗначений;

Для Каждого Элемент Из ИсходныйМассив Цикл

Если Список.НайтиПоЗначению(Элемент) = Неопределено Тогда

Список.Добавить(Элемент);

КонецЕсли;

КонецЦикла;

Результат = Список.ВыгрузитьЗначения();

Массив структур или сложных объектов

Методы Найти() и НайтиПоЗначению() сравнивают значения, и для структур корректное сравнение не гарантировано. Если массив содержит структуры, сравнивайте по ключевому полю: соберите Соответствие, где ключ — значение этого поля, а значение — сама структура.

Ссылки на объекты базы

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

Как проверить результат и каких ошибок избегать

Минимальная проверка — сравнить количество элементов до и после обработки и убедиться, что результирующий массив не пуст и содержит ожидаемые значения. Для контроля в отладчике используйте ИсходныйМассив.Количество() и Результат.Количество(), а также выборочно проверьте наличие ключевых элементов через Найти().

Дополнительный тест — убедиться, что в результате действительно нет повторов: пройдите по нему циклом и попробуйте найти каждый элемент дважды, либо сверните результат ещё раз и сравните количество. Если свёртка ничего не изменила, дубликатов нет.

Контрольные точки

Как проверить результат

Количество элементов после обработки
Норма

Меньше или равно исходному, массив не пустой

Тревожный признак

Результат пуст при непустом исходном массиве

Повторная свёртка результата
Норма

Количество элементов не меняется

Тревожный признак

Количество снова уменьшается — дубли остались

Наличие контрольных значений
Норма

Все ожидаемые элементы присутствуют по одному разу

Тревожный признак

Часть исходных значений потеряна

Частая ошибка — удаление элементов из массива в том же цикле, по которому идёт перебор. При удалении индексы сдвигаются, и часть элементов пропускается. Если нужно очистить исходный массив «на месте», обходите его с конца через Для Индекс = 0 По Массив.Количество()-1 в обратном порядке или просто замените его новым массивом.

Типичные ошибки
01
Удаление элементов из массива внутри прямого перебора — из-за сдвига индексов пропускаются элементы и остаются дубли
02
Сравнение значений разных типов — строка «001» и число 1 считаются разными, дубли не удаляются
03
Использование Найти() для структур — сравнение работает не так, как ожидается, дубли не находятся
04
Ожидание исходного порядка от Соответствия или свёрнутой таблицы — порядок не гарантирован, ломается последующая логика

Частые вопросы

Можно ли удалить дубликаты в массиве 1С одной встроенной функцией?

Нет, у типа Массив нет штатного метода удаления дубликатов. Ближайший «однострочный» вариант — выгрузить массив в ТаблицуЗначений и вызвать Свернуть(), но это всё равно требует нескольких строк кода.

Какой способ быстрее для большого массива?

Для больших объёмов оптимально Соответствие: проверка ключа выполняется быстро и не зависит от числа уже добавленных элементов. Перебор с Найти() на десятках тысяч элементов работает ощутимо медленнее.

Как удалить дубликаты, сохранив исходный порядок элементов?

Используйте перебор исходного массива с добавлением в новый массив только уникальных элементов. Для ускорения проверки вхождения держите рядом Соответствие, но добавляйте в результат в порядке обхода исходного массива.

Как удалить дубликаты строк в массиве без учёта регистра?

Приведите строки к одному регистру через ВРег() или НРег() при заполнении контрольного Соответствия, а в результирующий массив добавляйте исходное значение. Тогда «Товар» и «ТОВАР» будут считаться дубликатами.

Работают ли эти способы на клиенте в управляемых формах?

Да, все четыре подхода работают и на клиенте, и на сервере, так как Массив, Соответствие, СписокЗначений и ТаблицаЗначений доступны в обоих контекстах. Ограничений по директивам компиляции для этих операций нет.

Итог

Что важно запомнить

Дубликаты в массиве 1С удаляют перебором с проверкой Найти(), через Соответствие или свёртку ТаблицыЗначений. Выбор зависит от объёма данных и необходимости сохранить порядок. Не удаляйте элементы внутри прямого перебора и заранее приводите значения к единому типу.