Разбор номеров версий на реальные числа

Я хотел бы определить, если номер версии больше, чем другой. Номер версии может быть любым из следующих:

4

4.2

4.22.2

4.2.2.233

...поскольку номер версии находится вне моего контроля, поэтому я не мог сказать, сколько точек может фактически существовать в номере.

поскольку число на самом деле не является реальным числом, я не могу просто скажи,

Is 4.7 > 4.2.2

Как я могу преобразовать число, например 4.2.2, в реальное число, которое можно проверить на другой номер версии?

Я бы предпочел решение ColdFusion, но основная концепция также была бы в порядке.

6 ответов


это вырвано из кода обновления плагина в Блог Манго, и обновил немного. Он должен делать именно то, что вы хотите. Он возвращает 1, когда аргумент 1 больше, -1, когда аргумент 2 больше, и 0, когда они являются точными совпадениями. (Обратите внимание, что 4.0.1 будет точно соответствовать 4.0.1.0)

он использует функции списка CF вместо массивов, поэтому вы можете увидеть небольшое увеличение производительности, если вы переключитесь на массивы... но, эй, это работает!

function versionCompare( version1, version2 ){
    var len1 = listLen(arguments.version1, '.');
    var len2 = listLen(arguments.version2, '.');
    var i = 0;
    var piece1 = '';
    var piece2 = '';

    if (len1 gt len2){
        arguments.version2 = arguments.version2 & repeatString('.0', len1-len2);
    }else if (len2 gt len1){
        arguments.version1 = arguments.version1 & repeatString('.0', len2-len1);
    }

    for (i=1; i lte listLen(arguments.version1, '.'); i=i+1){
        piece1 = listGetAt(arguments.version1, i, '.');
        piece2 = listGetAt(arguments.version2, i, '.');

        if (piece1 neq piece2){
            if (piece1 gt piece2){
                return 1;
            }else{
                return -1;
            }
        }
    }

    //equal
    return 0;
}

запуск теста примера:

<cfoutput>#versionCompare('4.7', '4.2.2')#</cfoutput>

принты:

1


если версия 4 на самом деле означает 4.0.0, а версия 4.2 на самом деле означает 4.2.0, вы можете легко преобразовать версию в простое целое число.

предположим, что каждая часть версии находится между 0 и 99, тогда вы можете вычислить "целочисленную версию" из X. Y. Z следующим образом:

Version = X*100*100 + Y*100 + Z

если диапазоны больше или меньше, вы можете использовать коэффициенты выше или ниже 100.

сравнение версии становится простым.


разберите каждое число отдельно и сравните их итеративно.

if (majorVersion > 4 &&
    minorVersion > 2 &&
    revision > 2)
{
    // do something useful
}

// fail here

это, очевидно, не код CF, но вы понимаете идею.


номер версии-это в основном массив чисел с разделителями периода, поэтому вы можете проанализировать обе версии в массивы чисел, а затем сравнить каждый элемент в первом массиве с соответствующим элементом во втором массиве.

чтобы получить массив, сделать:

<cfset theArrayofNumbers = listToArray(yourVersionString, ".")>

и тогда вы можете сделать ваши сравнения.


вы можете разделить строку, содержащую версию, на периоды, затем начать с первого индекса и сравнить вниз, пока один не будет больше другого (или, если они равны, один содержит значение, другое нет).

боюсь, я никогда не писал в coldfusion, но это была бы основная логика, которой я бы следовал.

это грубый неоптимизированный пример:

bool IsGreater(string one, string two)
{
  int count;
  string[] v1;
  string[] v2;

  v1 = one.Split(".");
  v2 = two.Split(".");

  count = (one.Length > two.Length) ? one.Length : two.Length;

  for (int x=0;x<count;x++)
  {
     if (Convert.ToInt32(v1[x]) < Convert.ToInt32(v2[x]))
        return false;
     else if (Convert.ToInt32(v1[x]) > Convert.ToInt32(v2[x])
        return true;
  } // If they are the same it'll go to the next block.

  // If you're here, they both were equal for the shortest version's digit count.
  if (v1.Length > v2.Length)
     return true; // The first one has additional subversions so it's greater.
}

нет общего способа конвертировать номера версий нескольких частей в реальные числа, если нет ограничений на размер каждой части (например, 4.702.0 > 4.7.2?).

обычно вы определяете пользовательскую функцию сравнения, создавая последовательность или массив номера версии частей или компоненты, поэтому 4.7.2 представляется как [4, 7, 2], а 4.702.0-как [4, 702, 0]. Затем сравнить каждый элемент двух массивов, пока они не матч:

left = [4, 7, 2]
right = [4, 702, 0]

# check index 0
# left[0] == 4, right[0] == 4
left[0] == right[0]
# equal so far

# check index 1
# left[1] == 7, right[1] == 702
left[1] < right[1]
# so left < right

Я не знаю о ColdFusion, но на некоторых языках вы можете сделать прямое сравнение с массивами или последовательностями. Например, в Python:

>>> left = [4, 7, 2]
>>> right = [4, 702, 0]
>>> left < right
True