При решении задач автоматизации часто возникает необходимость получить набор случайных значений, в которых отсутствуют дубли. Стандартный генератор случайных чисел ГенераторСлучайныхЧисел выдает значения независимо, поэтому повторения неизбежны. Давайте разберем, как правильно реализовать алгоритм, гарантирующий уникальность элементов.
Этот способ интуитивно понятен: мы пытаемся получить случайное число и проверяем, есть ли оно уже в нашем массиве результатов. Если число уже содержится в массиве, генератор «выбрасывает» его и запрашивает новое значение, пока не получит уникальное.
Разберем реализацию этого метода по шагам:
Массив.ГенераторСлучайныхЧисел.Пока для заполнения, пока количество элементов не достигнет требуемого значения.Найти для проверки наличия сгенерированного числа в массиве.
МойМассив = Новый Массив();
Генератор = Новый ГенераторСлучайныхЧисел();
Пока МойМассив.Количество() < 20 Цикл
Число = Генератор.СлучайноеЧисло(0, 30);
Если МойМассив.Найти(Число) = Неопределено Тогда
МойМассив.Добавить(Число);
КонецЕсли;
КонецЦикла;
Этот метод хорошо работает для небольших выборок, однако при необходимости выбрать почти все числа из диапазона он может стать медленным из-за большого количества итераций поиска.
Если нам нужно получить уникальную последовательность быстро, рассмотрим более профессиональный подход. Мы заранее создаем массив всех возможных чисел (наш «пул»), а затем по очереди вытаскиваем из него случайные элементы. Выбранный элемент сразу удаляется из пула, что автоматически гарантирует отсутствие повторов.
Посмотрим на пример кода:
// Допустим, нам нужно 20 чисел из диапазона 0-30
ПределЧисел = 30;
ДлинаМассива = 20;
ИсходныйМассив = Новый Массив();
Для й = 0 По ПределЧисел Цикл
ИсходныйМассив.Добавить(й);
КонецЦикла;
Результат = Новый Массив();
ГСЧ = Новый ГенераторСлучайныхЧисел();
Для й = 1 По ДлинаМассива Цикл
// Выбираем случайный индекс из оставшихся элементов
Индекс = ГСЧ.СлучайноеЧисло(0, ИсходныйМассив.Количество() - 1);
Результат.Добавить(ИсходныйМассив[Индекс]);
// Удаляем элемент, чтобы он больше не выпал
ИсходныйМассив.Удалить(Индекс);
КонецЦикла;
Этот метод значительно эффективнее, так как мы точно знаем количество операций: оно равно размеру необходимой выборки. Мы не тратим время на бесконечные проверки и повторные генерации чисел.
При написании кода в 1С важно придерживаться стандартов разработки, чтобы ваши модули были читаемыми и поддерживаемыми.
й или ё). Используйте понятные названия, например, ИндексСчетчика или СлучайноеЗначение. Это поможет коллегам быстрее разобраться в вашем алгоритме.Массив является одной из самых быстрых структур. Использование Соответствие для проверки уникальности в подобных задачах часто избыточно и может привести к снижению производительности из-за накладных расходов на хэширование.Если задача становится комплексной и требует генерации очень больших массивов случайных данных, возможно, стоит рассмотреть перенос логики на сторону СУБД с использованием функций NEWID() или RAND() в запросах, однако для большинства прикладных задач 1С описанные выше алгоритмы будут работать идеально.