Разбор номеров версий в реальные числа - PullRequest
7 голосов
/ 02 марта 2010

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

4

4,2

4.22.2

4.2.2.233

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

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

Is 4.7 > 4.2.2

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

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

Ответы [ 6 ]

6 голосов
/ 02 марта 2010

Это извлечено из кода обновления плагина в Mango Blog и немного обновлено. Он должен делать именно то, что вы хотите. Он возвращает 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

3 голосов
/ 03 марта 2010

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

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

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

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

Сравнение версии становится легким.

1 голос
/ 02 марта 2010

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

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

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

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

1 голос
/ 02 марта 2010

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

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

// fail here

Это явно не код CF, но вы поняли.

0 голосов
/ 02 марта 2010

Нет общего способа преобразовать номера версий, состоящие из нескольких частей, в действительные числа, если нет ограничений на размер каждой части (например, 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
0 голосов
/ 02 марта 2010

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

Боюсь, я никогда не писал в 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.
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...