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

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

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

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

Прежде чем писать собственный велосипед, всегда проверяйте наличие готовых функций в Библиотеке Стандартных Подсистем (БСП). Это самый надежный способ, так как разработчики фирмы «1С» уже учли все нюансы — от разного количества сегментов в версии до некорректных входных данных.

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

Алгоритмический подход: избавляемся от вложенности

Если по каким-то причинам использование БСП невозможно, разберем, как сделать ваш код чище. Основная ошибка в исходном коде автора — вложенные условия, которые повторяют одну и ту же логику для каждого элемента массива. Посмотрим, как это решается через цикл Для...Цикл с оператором Прервать.

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


// Пример оптимального сравнения двух версий
Версия1 = СтрРазделить(СтрокаВерсии1, ".");
Версия2 = СтрРазделить(СтрокаВерсии2, ".");
Результат = 0;

Для Разряд = 0 По 3 Цикл
    Если Разряд >= Версия1.Количество() Или Разряд >= Версия2.Количество() Тогда
        Прервать;
    КонецЕсли;
    
    ТекущийРезультат = Число(Версия1[Разряд]) - Число(Версия2[Разряд]);
    Если ТекущийРезультат <> 0 Тогда
        Результат = ТекущийРезультат;
        Прервать;
    КонецЕсли;
КонецЦикла;

Этот подход позволяет избежать десятков строк кода. Мы приводим части строки к типу Число, что критически важно для корректного сравнения (например, чтобы 1.10 было больше, чем 1.2).

Математический метод приведения типов

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


// Метод приведения версии к числовому значению
Функция ВерсияВЧисло(МассивВерсии)
    Возврат МассивВерсии[0]*1000000 + МассивВерсии[1]*10000 + МассивВерсии[2]*100 + МассивВерсии[3];
КонецФункции

ЧислоВерсии1 = ВерсияВЧисло(РазделениеПервойВерсии);
ЧислоВерсии2 = ВерсияВЧисло(РазделениеВторойВерсии);

Если ЧислоВерсии1 > ЧислоВерсии2 Тогда
    Сообщить("Первая версия больше");
КонецЕсли;

Рекомендации по реализации

  1. Проверяйте типы данных: Всегда приводите части строки к Число перед сравнением. Посимвольное сравнение строк часто приводит к ошибкам, где 2 оказывается «больше» 10.
  2. Учитывайте количество разрядов: Если одна версия содержит «1.2», а другая «1.2.0.1», важно предусмотреть обработку отсутствующих индексов в массиве, чтобы система не выдавала ошибку обращения к несуществующему элементу коллекции.
  3. Нормализация: Если версии приходят в нестандартном виде, используйте СтрЗаменить для очистки строки от лишних символов перед тем, как выполнять СтрРазделить.
  4. Лаконичность: Используйте оператор ? (тернарный оператор) для компактных присвоений, если логика простая. Например, Редакция = ?(ВерсияА > ВерсияБ, ВерсияА, ВерсияБ).

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

← На главную