Js kullanarak yazılım sürüm numarası nasıl karşılaştırılır? (sadece sayı)


164

Yazılım sürüm numarası:

"1.0", "1.0.1", "2.0", "2.0.0.1", "2.0.1"

Bunu nasıl karşılaştırabilirim? Doğru siparişin:

"1.0", "1.0.1", "2.0", "2.0.0.1", "2.0.1"

Fikir basit ...: Üçüncü rakamdan sonra, üçüncü rakamdan sonra üçüncü rakamı okuyun .... Ama sürüm numarasını kayan sayıya dönüştüremiyorum .... Ayrıca sürüm numarasını da görebilirsiniz bu:

"1.0.0.0", "1.0.1.0", "2.0.0.0", "2.0.0.1", "2.0.1.0"

ve bu, arkasındaki fikrin ne olduğunu görmek için daha açık ... Ama, bir bilgisayar programına nasıl dönüştürülecek ?? Bunun nasıl sıralanacağı konusunda herhangi bir fikri olan var mı? Teşekkür ederim.


5
Bu iyi bir fizzbuzz tipi röportaj sorusu olurdu.
Steve Claridge

2
Bu nedenle, tüm yazılım sürüm numaraları 2001403 gibi tamsayılar olmalıdır. "2.0.14.3" gibi kolay bir şekilde görüntülemek istediğinizde, sürüm numarasını sunum zamanında biçimlendirirsiniz.
jarmod

2
Buradaki genel sorun Anlamsal Sürüm karşılaştırmalarıdır ve önemsiz değildir (bkz. Semver.org'daki # 11 ). Neyse ki, bunun için resmi bir kütüphane, npm için semantik versiyoner var .
Dan Dascalescu

1
Sömürgeleri karşılaştıran basit bir senaryo bulundu
vsync

Yanıtlar:


133

Bu karşılaştırmayı yapmak için temel fikir Array.split, giriş dizelerinden parça dizileri almak ve daha sonra iki diziden parça çiftlerini karşılaştırmak; parçalar eşit değilse hangi versiyonun daha küçük olduğunu biliyoruz.

Akılda tutulması gereken birkaç önemli ayrıntı vardır:

  1. Her çiftteki parçalar nasıl karşılaştırılmalıdır? Soru sayısal olarak karşılaştırmak istiyor, ancak sadece rakamlardan oluşmayan sürüm dizeleri varsa (örneğin, "1.0a")?
  2. Bir sürüm dizesinde diğerinden daha fazla parça varsa ne olur? Büyük olasılıkla "1.0", "1.0.1" den daha az olarak düşünülmelidir, ama "1.0.0" ne olacak?

Doğrudan kullanabileceğiniz bir uygulamanın kodu şöyledir ( belgelere bakın ):

function versionCompare(v1, v2, options) {
    var lexicographical = options && options.lexicographical,
        zeroExtend = options && options.zeroExtend,
        v1parts = v1.split('.'),
        v2parts = v2.split('.');

    function isValidPart(x) {
        return (lexicographical ? /^\d+[A-Za-z]*$/ : /^\d+$/).test(x);
    }

    if (!v1parts.every(isValidPart) || !v2parts.every(isValidPart)) {
        return NaN;
    }

    if (zeroExtend) {
        while (v1parts.length < v2parts.length) v1parts.push("0");
        while (v2parts.length < v1parts.length) v2parts.push("0");
    }

    if (!lexicographical) {
        v1parts = v1parts.map(Number);
        v2parts = v2parts.map(Number);
    }

    for (var i = 0; i < v1parts.length; ++i) {
        if (v2parts.length == i) {
            return 1;
        }

        if (v1parts[i] == v2parts[i]) {
            continue;
        }
        else if (v1parts[i] > v2parts[i]) {
            return 1;
        }
        else {
            return -1;
        }
    }

    if (v1parts.length != v2parts.length) {
        return -1;
    }

    return 0;
}

Bu sürüm parçaları doğal olarak karşılaştırır , karakter eklerini kabul etmez ve "1.7" nin "1.7.0" dan küçük olduğunu düşünür. Karşılaştırma modu sözlükbilimsel olarak değiştirilebilir ve daha kısa sürüm dizeleri isteğe bağlı üçüncü bağımsız değişken kullanılarak otomatik olarak sıfır dolgulu olabilir.

Bir JSFiddle yoktur çalışır "birim testleri" olduğunu burada ; Ripper234'ün çalışmasının biraz genişletilmiş bir versiyonudur (teşekkür ederim).

Önemli not: Bu kod Array.mapve kullanır Array.every, yani 9'dan önceki IE sürümlerinde çalışmaz. Bunları desteklemeniz gerekiyorsa, eksik yöntemler için çoklu dolgular sağlamanız gerekir.


16
İşte bazı birim testleri ile geliştirilmiş bir versiyon: jsfiddle.net/ripper234/Xv9WL/28
ripper234

5
Herkese selam, bu özeti testler ve her şeyle bir gitrepo'ya yuvarladım ve npm ve bower'a koydum, böylece projelerime daha kolay dahil edebiliyorum. github.com/gabe0x02/version_compare
Gabriel Littman

2
@ GabrielLittman: Hey, bunu yapmaya zaman ayırdığınız için teşekkürler! Ancak SO'daki tüm kodlar varsayılan olarak CC-BY-SA ile lisanslanmıştır . Bu, paketinizin GPL lisansına sahip olamayacağınız anlamına gelir. Avukatlığın burada kimseye ait olmadığını biliyorum, ama düzeltirseniz iyi olur.
Jon

2
@GabrielLittman: GPL, mevcut GPL koduyla temas eden tüm kodları GPL lisansına zorlamak zorunda olduğunuz için aslında çok kısıtlayıcıdır. Her neyse, gelecekteki referans için: iyi ve yaygın olarak kullanılan "ne istersen yap, ekli dizeler yok" lisansı MIT .
Jon

3
@ GabrielBittman: Semver karşılaştırmaları yapan deneyimli geliştiriciler tarafından yazılmış halihazırda kurulmuş kütüphaneler var .
Dan Dascalescu

82

semver

Npm tarafından kullanılan anlamsal sürüm ayrıştırıcısı.

$ npm yükleme sömürüsü

var semver = require('semver');

semver.diff('3.4.5', '4.3.7') //'major'
semver.diff('3.4.5', '3.3.7') //'minor'
semver.gte('3.4.8', '3.4.7') //true
semver.ltr('3.4.8', '3.4.7') //false

semver.valid('1.2.3') // '1.2.3'
semver.valid('a.b.c') // null
semver.clean(' =v1.2.3 ') // '1.2.3'
semver.satisfies('1.2.3', '1.x || >=2.5.0 || 5.0.0 - 7.2.3') // true
semver.gt('1.2.3', '9.8.7') // false
semver.lt('1.2.3', '9.8.7') // true

var versions = [ '1.2.3', '3.4.5', '1.0.2' ]
var max = versions.sort(semver.rcompare)[0]
var min = versions.sort(semver.compare)[0]
var max = semver.maxSatisfying(versions, '*')

Semantik Sürüm Oluşturma Bağlantısı :
https://www.npmjs.com/package/semver#prerelease-identifiers


8
Evet. Bu doğru cevaptır - sürümleri karşılaştırmak önemsizdir ( semver.org'da # 11'e bakın ) ve işi yapan üretim seviyesi kütüphaneler var.
Dan Dascalescu

7
node.js ve javascript farklı olduğu için teknik olarak doğru cevaplar değildir. Orijinal sorunun tarayıcı için daha fazla hedeflendiğini düşünmüştüm. Ama google beni buraya getirdi ve neyse ki ben düğüm kullanıyorum :)
Lee Gary

2
NodeJS yalnızca sunucu tarafı bir çözüm değildir. Elektron çerçevesi, masaüstü uygulamaları için bir nodeJS yerleştirdi. Aslında aradığım cevap bu.
Anthony Raymond

2
semver bir npm paketi, herhangi bir JS ortamında kullanılabilir! BU doğru cevaptır
neiker

4
@artuska iyi sonra sadece semver-karşılaştırmak gibi başka bir paket için gitmek - 233B (0.5kB daha az!) gzipped:)
kano

50
// Return 1 if a > b
// Return -1 if a < b
// Return 0 if a == b
function compare(a, b) {
    if (a === b) {
       return 0;
    }

    var a_components = a.split(".");
    var b_components = b.split(".");

    var len = Math.min(a_components.length, b_components.length);

    // loop while the components are equal
    for (var i = 0; i < len; i++) {
        // A bigger than B
        if (parseInt(a_components[i]) > parseInt(b_components[i])) {
            return 1;
        }

        // B bigger than A
        if (parseInt(a_components[i]) < parseInt(b_components[i])) {
            return -1;
        }
    }

    // If one's a prefix of the other, the longer one is greater.
    if (a_components.length > b_components.length) {
        return 1;
    }

    if (a_components.length < b_components.length) {
        return -1;
    }

    // Otherwise they are the same.
    return 0;
}

console.log(compare("1", "2"));
console.log(compare("2", "1"));

console.log(compare("1.0", "1.0"));
console.log(compare("2.0", "1.0"));
console.log(compare("1.0", "2.0"));
console.log(compare("1.0.1", "1.0"));

Bence satır: var len = Math.min(a_components.length, b_components.length);2.0.1.1 ve 2.0.1 sürümlerinin eşit muamele görmesine neden olur mu?
Jon Egerton

1
Hayýr. Döngüden hemen sonra bak! Bir dize diğerinin bir önekiyse (yani döngü sona ulaşırsa), daha uzun olan daha yüksek olarak alınır.
Joe

Belki de yorumda İngilizce dilini tökezledim ...
Joe

@Joe biliyorum biraz eski bir cevap ama işlevini kullanıyordum. Test a = '7'veb = '7.0' geri dönüşler, -1çünkü 7.0 daha uzun. Bunun için bir öneriniz var mı? ( console.log(compare("7", "7.0")); //returns -1)
RaphaelDDL

Sanırım bu tanımlanmamış davranış başlığı altında geliyor. Bu sürüm numaralarına sahipseniz, mantığı gereksinimlerinize uyacak şekilde değiştirebileceğinizden eminim.
Joe

48

Bu çok küçük, ancak çok hızlı karşılaştırma işlevi , her bir uzunluktaki sürüm numaralarını ve segment başına herhangi bir sayı boyutunu alır .

Dönüş değerleri:
- bir sayı < 0ise <b
- bir sayı > 0a> b
- 0a = b ise

Böylece Array.sort () için karşılaştırma fonksiyonu olarak kullanabilirsiniz ;

EDIT: "1" ve "1.0.0" eşit olarak tanımak için sıfırlar sıyırma bugfixed sürümü

function cmpVersions (a, b) {
    var i, diff;
    var regExStrip0 = /(\.0+)+$/;
    var segmentsA = a.replace(regExStrip0, '').split('.');
    var segmentsB = b.replace(regExStrip0, '').split('.');
    var l = Math.min(segmentsA.length, segmentsB.length);

    for (i = 0; i < l; i++) {
        diff = parseInt(segmentsA[i], 10) - parseInt(segmentsB[i], 10);
        if (diff) {
            return diff;
        }
    }
    return segmentsA.length - segmentsB.length;
}

// TEST
console.log(
['2.5.10.4159',
 '1.0.0',
 '0.5',
 '0.4.1',
 '1',
 '1.1',
 '0.0.0',
 '2.5.0',
 '2',
 '0.0',
 '2.5.10',
 '10.5',
 '1.25.4',
 '1.2.15'].sort(cmpVersions));
// Result:
// ["0.0.0", "0.0", "0.4.1", "0.5", "1.0.0", "1", "1.1", "1.2.15", "1.25.4", "2", "2.5.0", "2.5.10", "2.5.10.4159", "10.5"]


'0.0' ve '0.0.0' ile başarısız oldu. Keman bakın: jsfiddle.net/emragins/9e9pweqg
emragins

1
@emragins Bunu ne zaman yapmanız gerekir?
Skylar Ittner

1
@emragins: Nerede başarısız olduğunu görmüyorum. 0.0 ve 0.0.0 eşit["0.0.0", "0.0", "0.4.1", "0.5", "1.0.0", "1", "1.1", "1.2.15", "1.25.4", "2", "2.5.0", "2.5.10", "2.5.10.4159", "10.5"] olduğu için kodunuzun çıkışının nerede olduğu çıktısını verir ["0.0", "0.0.0", "0.4.1", "0.5", "1", "1.0.0", "1.1", "1.2.15", "1.25.4", "2", "2.5.0", "2.5.10", "2.5.10.4159", "10.5"] , yani '0.0' ın ​​'0.0.0'dan önce olup olmadığı önemsizdir.
LeJared

Bunun olağan bir nokta olduğuna katılıyorum. Bunu sürümlere benzer bir şekilde sıralayan github.com/jonmiles/bootstrap-treeview ile kullanıyorum , sadece gerçekten ebeveyn / alt düğümler ve dizinleri. Ör. Ebeveyn: 0.0, çocuk: 0.0.0, 0.0.1. Neden umursadığım hakkında daha fazla ayrıntı için bu konuya bakın: github.com/jonmiles/bootstrap-treeview/issues/251
emragins

1
Cevabı buradan görebilirsiniz stackoverflow.com/questions/6611824/why-do-we-need-to-use-radix . Daha eski tarayıcılar, belirtilmezse radix parametresini tahmin etmek için kullanılır. "1.09.12" deki orta kısım gibi bir sayı dizesinde önde gelen sıfır, beklenen sayı 9 yerine 0 sayısı ile sonuçlanacak şekilde radix = 8 ile ayrıştırılır.
LeJared

14

Http://java.com/js/deployJava.js adresinden alınmıştır :

    // return true if 'installed' (considered as a JRE version string) is
    // greater than or equal to 'required' (again, a JRE version string).
    compareVersions: function (installed, required) {

        var a = installed.split('.');
        var b = required.split('.');

        for (var i = 0; i < a.length; ++i) {
            a[i] = Number(a[i]);
        }
        for (var i = 0; i < b.length; ++i) {
            b[i] = Number(b[i]);
        }
        if (a.length == 2) {
            a[2] = 0;
        }

        if (a[0] > b[0]) return true;
        if (a[0] < b[0]) return false;

        if (a[1] > b[1]) return true;
        if (a[1] < b[1]) return false;

        if (a[2] > b[2]) return true;
        if (a[2] < b[2]) return false;

        return true;
    }

Basit, ancak üç sürüm alanı ile sınırlıdır.
Dan Dascalescu

11

Burada istediğimi yapan bir işlev bulunamadı. Ben de kendim yazdım. Bu benim katkım. Umarım birisi faydalı bulur.

Artıları:

  • İsteğe bağlı uzunluktaki sürüm dizelerini işler. '1' veya '1.1.1.1.1'.

  • Belirtilmezse, her bir değeri 0 olarak ayarlar. Bir dizenin daha uzun olması, daha büyük bir sürüm olduğu anlamına gelmez. ('1', '1.0' ve '1.0.0.0' ile aynı olmalıdır.)

  • Dizeleri değil sayıları karşılaştırın. ('3' <'21' doğru olmalıdır. Yanlış değil.)

  • Döngüdeki yararsız karşılaştırmalar için zaman kaybetmeyin. (== ile karşılaştırılıyor)

  • Kendi karşılaştırıcınızı seçebilirsiniz.

Eksileri:

  • Sürüm dizesindeki harfleri işlemez. (Bunun nasıl çalışacağını bilmiyorum?)

Kodum, Jon'un kabul ettiği cevaba benzer :

function compareVersions(v1, comparator, v2) {
    "use strict";
    var comparator = comparator == '=' ? '==' : comparator;
    if(['==','===','<','<=','>','>=','!=','!=='].indexOf(comparator) == -1) {
        throw new Error('Invalid comparator. ' + comparator);
    }
    var v1parts = v1.split('.'), v2parts = v2.split('.');
    var maxLen = Math.max(v1parts.length, v2parts.length);
    var part1, part2;
    var cmp = 0;
    for(var i = 0; i < maxLen && !cmp; i++) {
        part1 = parseInt(v1parts[i], 10) || 0;
        part2 = parseInt(v2parts[i], 10) || 0;
        if(part1 < part2)
            cmp = 1;
        if(part1 > part2)
            cmp = -1;
    }
    return eval('0' + comparator + cmp);
}

Örnekler :

compareVersions('1.2.0', '==', '1.2'); // true
compareVersions('00001', '==', '1.0.0'); // true
compareVersions('1.2.0', '<=', '1.2'); // true
compareVersions('2.2.0', '<=', '1.2'); // false

bu sürüm bence onaylanan cevap daha iyidir!
user3807877

1
Karşılaştırma parametresi kontrol edilmemiş kullanıcı girişi ile kullanılırsa bu işlev kod enjeksiyonuna eğilimlidir! Örnek: comparVersions ('1.2', '== 0; uyarı ("cotcha");', '1.2');
LeJared

@LeJared True. Yazdığımda kullanıcı tarafından gönderilen kodla birlikte kullanmayacaktık. Muhtemelen bir con olarak yetiştirmeliydim. Şimdi bu olasılığı ortadan kaldırmak için kodu güncelledim. Şimdi, webpack ve diğer node.js paketleyicileri yaygınlaştığında, Mohammed Akdim'in yukarıdaki semver kullanarak cevabının neredeyse her zaman bu soruya doğru cevap olacağını öneririm .
Viktor

10

Basit ve kısa fonksiyon:

function isNewerVersion (oldVer, newVer) {
  const oldParts = oldVer.split('.')
  const newParts = newVer.split('.')
  for (var i = 0; i < newParts.length; i++) {
    const a = parseInt(newParts[i]) || 0
    const b = parseInt(oldParts[i]) || 0
    if (a > b) return true
    if (a < b) return false
  }
  return false
}

Testler:

isNewerVersion('1.0', '2.0') // true
isNewerVersion('1.0', '1.0.1') // true
isNewerVersion('1.0.1', '1.0.10') // true
isNewerVersion('1.0.1', '1.0.1') // false
isNewerVersion('2.0', '1.0') // false
isNewerVersion('2', '1.0') // false
isNewerVersion('2.0.0.0.0.1', '2.1') // true
isNewerVersion('2.0.0.0.0.1', '2.0') // false

Şunlarla basitleştirebilirsiniz: Şunlarla const a = ~~ newParts [i]; Aslında bu, bir dizgiyi bir tamsayıya dönüştürmenin en etkili yoludur; değişken tanımsızsa veya sayısal olmayan karakterler içeriyorsa 0 döndürür.
vanowm

5

Bu fikir daha önce görmediğim bir bağlantıda ziyaret edilmişse beni affet.

Ben parçaları gibi ağırlıklı bir toplam dönüştürülmesi ile bazı başarı oldu:

partSum = this.major * Math.Pow(10,9);
partSum += this.minor * Math.Pow(10, 6);
partSum += this.revision * Math.Pow(10, 3);
partSum += this.build * Math.Pow(10, 0);

Hangi karşılaştırmaları çok kolay (bir çift karşılaştırma) yaptı. Sürüm alanlarımız asla 4 basamaktan fazla değildir.

7.10.2.184  -> 7010002184.0
7.11.0.1385 -> 7011001385.0

Umarım bu birisine yardımcı olur, çünkü birden fazla koşul biraz abartılı görünüyor.



5

Burada, herhangi bir sayıda alt sürüm, dolgulu sıfır ve hatta harfli sayılarla çalışan başka bir kısa sürüm (1.0.0b3)

function compareVer(a, b)
{
    //treat non-numerical characters as lower version
    //replacing them with a negative number based on charcode of each character
    function fix(s)
    {
        return "." + (s.toLowerCase().charCodeAt(0) - 2147483647) + ".";
    }
    a = ("" + a).replace(/[^0-9\.]/g, fix).split('.');
    b = ("" + b).replace(/[^0-9\.]/g, fix).split('.');
    var c = Math.max(a.length, b.length);
    for (var i = 0; i < c; i++)
    {
        //convert to integer the most efficient way
        a[i] = ~~a[i];
        b[i] = ~~b[i];
        if (a[i] > b[i])
            return 1;
        else if (a[i] < b[i])
            return -1;
    }
    return 0;
}

Çıktı:

0 : a = b

1 : a> b

-1 : a <b

1.0.0.0.0.0 = 1.0
1.0         < 1.0.1
1.0b1       < 1.0
1.0a        < 1.0b
1.1         > 1.0.1b
1.1alpha    < 1.1beta
1.1rc1      > 1.1beta
1.0001      > 1.00000.1.0.0.0.01

https://jsfiddle.net/vanowm/p7uvtbor/


5

2017 yanıtı:

v1 = '20.0.12'; 
v2 = '3.123.12';

compareVersions(v1,v2) 
// return positive: v1 > v2, zero:v1 == v2, negative: v1 < v2 
function compareVersions(v1, v2) {
        v1= v1.split('.')
        v2= v2.split('.')
        var len = Math.max(v1.length,v2.length)
        /*default is true*/
        for( let i=0; i < len; i++)
            v1 = Number(v1[i] || 0);
            v2 = Number(v2[i] || 0);
            if (v1 !== v2) return v1 - v2 ;
            i++;
        }
        return 0;
    }

Modern tarayıcılar için en basit kod:

 function compareVersion2(ver1, ver2) {
      ver1 = ver1.split('.').map( s => s.padStart(10) ).join('.');
      ver2 = ver2.split('.').map( s => s.padStart(10) ).join('.');
      return ver1 <= ver2;
 }

Buradaki fikir sayıları dize şeklinde karşılaştırmaktır. karşılaştırmanın çalışması için iki dizenin aynı uzunlukta olması gerekir. yani:

"123" > "99" olmak "123" > "099"
kısa numara doldurma "düzeltme" karşılaştırma

Burada her parçayı sıfırlarla 10 uzunluğa dolduruyorum, sonra cevap için basit bir dize karşılaştırın

Misal :

var ver1 = '0.2.10', ver2=`0.10.2`
//become 
ver1 = '0000000000.0000000002.0000000010'
ver2 = '0000000000.0000000010.0000000002'
// then it easy to see that
ver1 <= ver2 // true

compareVersion2tam olarak ne olduğunu açıklar mısın?
Usman Wali

İyi, o zaman daha iyi uyumluluk substringyerine kullanabilirsiniz padStartyani var zeros = "0000000000"; '0.2.32'.split('.').map( s => zeros.substring(0, zeros.length-s.length) + s ).join('.') size verecek 0000000000.0000000002.0000000032:)
Usman Wali


4

Buradaki cevapların çoğundan daha az ayrıntılı cevabım

/**
 * Compare two semver versions. Returns true if version A is greater than
 * version B
 * @param {string} versionA
 * @param {string} versionB
 * @returns {boolean}
 */
export const semverGreaterThan = function(versionA, versionB){
  var versionsA = versionA.split(/\./g),
    versionsB = versionB.split(/\./g)
  while (versionsA.length || versionsB.length) {
    var a = Number(versionsA.shift()), b = Number(versionsB.shift())
    if (a == b)
      continue
    return (a > b || isNaN(b))
  }
  return false
}

1
bir modül yapmalı ve node.js'ye koymalısınız. o zamana kadar, size atıfta bulunarak kodunuzu çalıyorum. bunun için teşekkür ederim.
r3wt

3

Bu sorunun zaten çok fazla olmasına rağmen fazla yanıtı , her biri kendi arka bahçesinde yetiştirilen çözümlerini teşvik ederken, bunun için (savaş) test edilmiş kütüphanelerin ekosistemine sahibiz.

NPM , GitHub , X ile ilgili hızlı bir arama bize bazı güzel kütüphaneler verecek ve bazılarından geçmek istiyorum:

semver-compareEğer sürüm numaralarına göre sıralamak istiyorsanız kütüphanenin maruz yöntem dönüşleri, özellikle yararlıdır büyük bir hafif (~ 230B) lib olduğu -1, 0ya da 1uygun bir şekilde.

Lib'in çekirdeği:

module.exports = function cmp (a, b) {
    var pa = a.split('.');
    var pb = b.split('.');
    for (var i = 0; i < 3; i++) {
        var na = Number(pa[i]);
        var nb = Number(pb[i]);
        if (na > nb) return 1;
        if (nb > na) return -1;
        if (!isNaN(na) && isNaN(nb)) return 1;
        if (isNaN(na) && !isNaN(nb)) return -1;
    }
    return 0;
};

compare-semver oldukça ağırdır (~ 4.4kB gzip), ancak bir sürüm yığınının min / maks'ini bulmak veya sağlanan sürümün benzersiz veya bir koleksiyondaki herhangi bir şeyden daha az olup olmadığını bulmak gibi bazı güzel benzersiz karşılaştırmalara izin verir. sürümleri.

compare-versionsbaşka bir küçük lib (~ 630B gzip) ve spesifikasyonu güzelce izler, yani sürümleri alfa / beta bayrakları ve hatta joker karakterlerle (küçük / yama sürümleri gibi) karşılaştırabilirsiniz: 1.0.xveya1.0.* )

Önemli olan: Seçtiğiniz paket yöneticiniz aracılığıyla iyi, (birim-) test edilmiş sürümleri bulabiliyorsanız, StackOverflow'dan kodu kopyalayıp yapıştırmaya her zaman gerek yoktur .


3

Benzer bir sorunla karşılaştım ve zaten bunun için bir çözüm oluşturmuştum. Denemekten çekinmeyin.

Bu döndürür 0için equal, 1sürüm ise greaterve -1o iseless

function compareVersion(currentVersion, minVersion) {
  let current = currentVersion.replace(/\./g," .").split(' ').map(x=>parseFloat(x,10))
  let min = minVersion.replace(/\./g," .").split(' ').map(x=>parseFloat(x,10))

  for(let i = 0; i < Math.max(current.length, min.length); i++) {
    if((current[i] || 0) < (min[i] || 0)) {
      return -1
    } else if ((current[i] || 0) > (min[i] || 0)) {
      return 1
    }
  }
  return 0
}


console.log(compareVersion("81.0.1212.121","80.4.1121.121"));
console.log(compareVersion("81.0.1212.121","80.4.9921.121"));
console.log(compareVersion("80.0.1212.121","80.4.9921.121"));
console.log(compareVersion("4.4.0","4.4.1"));
console.log(compareVersion("5.24","5.2"));
console.log(compareVersion("4.1","4.1.2"));
console.log(compareVersion("4.1.2","4.1"));
console.log(compareVersion("4.4.4.4","4.4.4.4.4"));
console.log(compareVersion("4.4.4.4.4.4","4.4.4.4.4"));
console.log(compareVersion("0","1"));
console.log(compareVersion("1","1"));
console.log(compareVersion("1","1.0.00000.0000"));
console.log(compareVersion("","1"));
console.log(compareVersion("10.0.1","10.1"));


2

Fikir iki versiyonu karşılaştırmak ve hangisinin en büyük olduğunu bilmek. "." ve vektörün her bir pozisyonunu diğeriyle karşılaştırıyoruz.

// Return 1  if a > b
// Return -1 if a < b
// Return 0  if a == b

function compareVersions(a_components, b_components) {

   if (a_components === b_components) {
       return 0;
   }

   var partsNumberA = a_components.split(".");
   var partsNumberB = b_components.split(".");

   for (var i = 0; i < partsNumberA.length; i++) {

      var valueA = parseInt(partsNumberA[i]);
      var valueB = parseInt(partsNumberB[i]);

      // A bigger than B
      if (valueA > valueB || isNaN(valueB)) {
         return 1;
      }

      // B bigger than A
      if (valueA < valueB) {
         return -1;
      }
   }
}

Destansı bir cevap, tam olarak aradığım şey.
Vince

2
// Returns true if v1 is bigger than v2, and false if otherwise.
function isNewerThan(v1, v2) {
      v1=v1.split('.');
      v2=v2.split('.');
      for(var i = 0; i<Math.max(v1.length,v2.length); i++){
        if(v1[i] == undefined) return false; // If there is no digit, v2 is automatically bigger
        if(v2[i] == undefined) return true; // if there is no digit, v1 is automatically bigger
        if(v1[i] > v2[i]) return true;
        if(v1[i] < v2[i]) return false;
      }
      return false; // Returns false if they are equal
    }

1
SO'ya hoş geldiniz. Bu sorunun zaten birçok iyi yanıtı var, lütfen yeni bir şey eklemediğiniz sürece yeni cevaplar eklemekten kaçının.
dahili

1

replace()İşlevi yalnızca dizede ilk oluşumunu yerini alır. Yani, .ile değiştirelim ,. Daha sonra hepsini silmek .ve yapmak ,için .tekrar yüzer ayrıştırmak.

for(i=0; i<versions.length; i++) {
    v = versions[i].replace('.', ',');
    v = v.replace(/\./g, '');
    versions[i] = parseFloat(v.replace(',', '.'));
}

Son olarak, sıralayın:

versions.sort();

1

Bu blog yayınına göz atın . Bu işlev sayısal sürüm numaraları için çalışır.

function compVersions(strV1, strV2) {
  var nRes = 0
    , parts1 = strV1.split('.')
    , parts2 = strV2.split('.')
    , nLen = Math.max(parts1.length, parts2.length);

  for (var i = 0; i < nLen; i++) {
    var nP1 = (i < parts1.length) ? parseInt(parts1[i], 10) : 0
      , nP2 = (i < parts2.length) ? parseInt(parts2[i], 10) : 0;

    if (isNaN(nP1)) { nP1 = 0; }
    if (isNaN(nP2)) { nP2 = 0; }

    if (nP1 != nP2) {
      nRes = (nP1 > nP2) ? 1 : -1;
      break;
    }
  }

  return nRes;
};

compVersions('10', '10.0'); // 0
compVersions('10.1', '10.01.0'); // 0
compVersions('10.0.1', '10.0'); // 1
compVersions('10.0.1', '10.1'); // -1

1

Örneğin, mevcut jQuery sürümü az 1,8 olup olmadığını kontrol etmek istiyorsanız, parseFloat($.ui.version) < 1.8 )bir verecekti yanlış versiyonu "1.10.1" ise, parseFloat beri ( "1.10.1") döner sonucu 1.1. Bir dize beri de yanlış gider karşılaştırmak "1.8" < "1.10"için değerlendirirfalse .

Yani böyle bir teste ihtiyacımız var

if(versionCompare($.ui.version, "1.8") < 0){
    alert("please update jQuery");
}

Aşağıdaki işlev bunu doğru bir şekilde işler:

/** Compare two dotted version strings (like '10.2.3').
 * @returns {Integer} 0: v1 == v2, -1: v1 < v2, 1: v1 > v2
 */
function versionCompare(v1, v2) {
    var v1parts = ("" + v1).split("."),
        v2parts = ("" + v2).split("."),
        minLength = Math.min(v1parts.length, v2parts.length),
        p1, p2, i;
    // Compare tuple pair-by-pair. 
    for(i = 0; i < minLength; i++) {
        // Convert to integer if possible, because "8" > "10".
        p1 = parseInt(v1parts[i], 10);
        p2 = parseInt(v2parts[i], 10);
        if (isNaN(p1)){ p1 = v1parts[i]; } 
        if (isNaN(p2)){ p2 = v2parts[i]; } 
        if (p1 == p2) {
            continue;
        }else if (p1 > p2) {
            return 1;
        }else if (p1 < p2) {
            return -1;
        }
        // one operand is NaN
        return NaN;
    }
    // The longer tuple is always considered 'greater'
    if (v1parts.length === v2parts.length) {
        return 0;
    }
    return (v1parts.length < v2parts.length) ? -1 : 1;
}

İşte bazı örnekler:

// compare dotted version strings
console.assert(versionCompare("1.8",      "1.8.1")    <   0);
console.assert(versionCompare("1.8.3",    "1.8.1")    >   0);
console.assert(versionCompare("1.8",      "1.10")     <   0);
console.assert(versionCompare("1.10.1",   "1.10.1")   === 0);
// Longer is considered 'greater'
console.assert(versionCompare("1.10.1.0", "1.10.1")   >   0);
console.assert(versionCompare("1.10.1",   "1.10.1.0") <   0);
// Strings pairs are accepted
console.assert(versionCompare("1.x",      "1.x")      === 0);
// Mixed int/string pairs return NaN
console.assert(isNaN(versionCompare("1.8", "1.x")));
//works with plain numbers
console.assert(versionCompare("4", 3)   >   0);

Canlı bir örnek ve test paketi için buraya bakın: http://jsfiddle.net/mar10/8KjvP/


Arghh, sadece ripper234'ün birkaç ay önce yorumlarda bir benzer URL yayınladığını fark etti. Her neyse, cevabımı burada
tutuyorum

Bu da bu durumlarda başarısız olur (çoğu varyant gibi): versionCompare ('1.09', '1.1') versionCompare ('1.702', '1.8') ile aynı şekilde "1" değerini döndürür.
shaman.sir

Kod, doğru olduğunu düşünüyorum "1.09"> "1.1" ve "1.702"> "1.8" değerlendirir. Kabul etmiyorsanız: fikrinizi destekleyen bir kaynağa işaret edebilir misiniz?
mar10

Bu sizin ilkelerinize bağlıdır - bildiğim gibi katı bir kural falan yok. Kaynaklarla ilgili olarak, "Artan diziler" içindeki "Yazılım sürümlendirme" için wikipedia makalesi, 1.81'in 1.8'in küçük bir sürümü olabileceğini, bu nedenle 1.8'in 1.80 olarak okunması gerektiğini söylüyor. Anlamsal sürümleme makalesi semver.org/spec/v2.0.0.html ayrıca 1.9.0 -> 1.10.0 -> 1.11.0, yani 1.9.0'ın buna kıyasla 1.90.0 olarak değerlendirildiğini söylüyor. Yani, bu mantığı izleyerek, 1.702 sürümü 1.800 olarak kabul edilen 1.8 sürümünden önceydi.
shaman.sir

1
Bazı kuralların 1.8 <1.81 <1.9 olduğunu kabul ediyorum. Ancak semverde 1.81 yerine 1.8.1 kullanırsınız. Semver (anladığım kadarıyla), bir parçayı arttırmanın her zaman 'daha sonraki' bir versiyon üreteceği varsayımı etrafında tanımlanmıştır, bu nedenle 1.8 <1.8.1 <1.9 <1.10 <1.81 <1.90 <1.100. Bunun iki basamakla sınırlı olduğunu gösteren bir işaret görmüyorum. Bu yüzden kodumun semver ile tamamen uyumlu olduğunu söyleyebilirim.
mar10

1

İşte burada diğer cevaplardan esinlenerek Array.sort ile kullanım için uygun bir kahve uygulaması:

# Returns > 0 if v1 > v2 and < 0 if v1 < v2 and 0 if v1 == v2
compareVersions = (v1, v2) ->
  v1Parts = v1.split('.')
  v2Parts = v2.split('.')
  minLength = Math.min(v1Parts.length, v2Parts.length)
  if minLength > 0
    for idx in [0..minLength - 1]
      diff = Number(v1Parts[idx]) - Number(v2Parts[idx])
      return diff unless diff is 0
  return v1Parts.length - v2Parts.length


bu düzgün çalışmıyor .. sonuç burada .. sonuç ['1.1.1', '2.1.1', '3.3.1.0', '3.1.1.0']
ertan2002

1

Sürümleri sıralamak için bir düğüm modülü yazdım, burada bulabilirsiniz: version-sort

Özellikler :

  • dizilerin sınırı yoktur '1.0.1.5.53.54654.114.1.154.45' çalışır
  • dizi uzunluğu sınırı yok: '1.1546515465451654654654654138754431574364321353734' çalışıyor
  • nesneleri sürüme göre sıralayabilir (bkz. README)
  • aşamalar (alfa, beta, rc1, rc2 gibi)

Başka bir özelliğe ihtiyacınız varsa bir sorunu açmaktan çekinmeyin.


1

Bu, nokta ile ayrılmış herhangi bir uzunluktaki sayısal sürümler için geçerlidir. Yalnızca myVersion> = minimumVersion ise true değerini döndürür ve sürüm 1'in 1.0'dan küçük, sürüm 1.1'in 1.1.0'dan küçük olduğunu varsayar. Sayıları kabul etmek (sadece bir dizeye dönüştürmek) ve onaltılık yapmak veya ayırıcıyı dinamik yapmak gibi ek koşullar eklemek oldukça basit olmalıdır (sadece bir ayırıcı parametresi ekleyin ve sonra "." Parametresini değiştirin)

function versionCompare(myVersion, minimumVersion) {

    var v1 = myVersion.split("."), v2 = minimumVersion.split("."), minLength;   

    minLength= Math.min(v1.length, v2.length);

    for(i=0; i<minLength; i++) {
        if(Number(v1[i]) > Number(v2[i])) {
            return true;
        }
        if(Number(v1[i]) < Number(v2[i])) {
            return false;
        }           
    }

    return (v1.length >= v2.length);
}

İşte bazı testler:

console.log(versionCompare("4.4.0","4.4.1"));
console.log(versionCompare("5.24","5.2"));
console.log(versionCompare("4.1","4.1.2"));
console.log(versionCompare("4.1.2","4.1"));
console.log(versionCompare("4.4.4.4","4.4.4.4.4"));
console.log(versionCompare("4.4.4.4.4.4","4.4.4.4.4"));
console.log(versionCompare("0","1"));
console.log(versionCompare("1","1"));
console.log(versionCompare("","1"));
console.log(versionCompare("10.0.1","10.1"));

Alternatif olarak burada özyinelemeli bir sürüm var

function versionCompare(myVersion, minimumVersion) {
  return recursiveCompare(myVersion.split("."),minimumVersion.split("."),Math.min(myVersion.length, minimumVersion.length),0);
}

function recursiveCompare(v1, v2,minLength, index) {
  if(Number(v1[index]) < Number(v2[index])) {
    return false;
  }
  if(Number(v1[i]) < Number(v2[i])) {
    return true;
    }
  if(index === minLength) {
    return (v1.length >= v2.length);
  }
  return recursiveCompare(v1,v2,minLength,index+1);
}

1

Onları karşılaştırmanın en basit yolunu buluyorum, ne istediğinizden emin değilim. Konsolda kodun altında çalıştırdığımda, mantıklı ve sort () yöntemini kullanarak, dizi dizesinin sıralanmış dizisini alabilirim. alfabetik sıraya dayanır.

"1.0" < "1.0.1" //true
var arr = ["1.0.1", "1.0", "3.2.0", "1.3"]
arr.sort();     //["1.0", "1.0.1", "1.3", "3.2.0"]

3
İki basamaklı sürüm numaraları için iyi çalışmaz, örneğin, 1.10.0.
Leukipp

1

Sen kullanabilirsiniz String#localeCompareileoptions

duyarlılık

Dizelerde hangi farklılıkların sıfır olmayan sonuç değerlerine yol açması gerekir. Olası değerler:

  • "base": Yalnızca temel harflerden farklı dizeler eşitsiz olarak karşılaştırılır. Örnekler: a ≠ b, a = á, a = A.
  • "accent": Yalnızca temel harflerden veya aksanlardan farklı dizeler ve diğer aksan işaretleri eşitsiz olarak karşılaştırılır. Örnekler: a ≠ b, a ≠ á, a = A.
  • "case": Yalnızca temel harf veya büyük / küçük harf farkı farklı olan dizeler eşitsiz olarak karşılaştırılır. Örnekler: a ≠ b, a = á, a ≠ A.
  • "variant": Taban harfleri, aksanlar ve diğer aksan işaretleri veya büyüklükleri bakımından farklı olan dizeler eşitsiz olarak karşılaştırılır. Diğer farklılıklar da dikkate alınabilir. Örnekler: a ≠ b, a ≠ á, a ≠ A.

"Sort" kullanımı için varsayılan "varyant" tır; yerel arama "arama" kullanımına bağlıdır.

sayısal

Sayısal harmanlamanın kullanılıp kullanılmayacağı, "1" <"2" <"10". Olası değerler trueve false; varsayılan değer false. Bu seçenek bir options özelliği aracılığıyla veya bir Unicode uzantı anahtarı aracılığıyla ayarlanabilir; her ikisi de sağlanırsa, optionsözellik önceliklidir. Bu mülkü desteklemek için uygulamalara gerek yoktur.

var versions = ["2.0.1", "2.0", "1.0", "1.0.1", "2.0.0.1"];

versions.sort((a, b) => a.localeCompare(b, undefined, { numeric: true, sensitivity: 'base' }));

console.log(versions);


Bu gerçekten nasıl çalışıyor? undefinedYukarıdakiler nedir , Dil? Ben başkalarını okurken bunu göndermek için nasıl geliyor;)
mplungjan

undefinedyerliler kısmı, burada kullanılmaz.
Nina Scholz

0

onları sayılara dönüştürüp sonra boyutuna göre sıralayamadınız mı? Uzunluğu <4 olan numaralara 0'ları ekleyin

konsolda oynanan:

$(["1.0.0.0", "1.0.1.0", "2.0.0.0", "2.0.0.1", "2.0.1", "3.0"]).each(function(i,e) {
    var n =   e.replace(/\./g,"");
    while(n.length < 4) n+="0" ; 
    num.push(  +n  )
});

sürüm ne kadar büyük olursa, o kadar büyük sayı olur. Düzenleme: muhtemelen daha büyük sürüm serilerini hesaba katmak için ayarlanması gerekiyor


Bu sadece bir örnekti, çünkü bazı şeyleri kendisi yapmak zorunda: P 4 yerine, en büyük versiyonun sahip olduğu sayıları alın, daha sonra olanları 0'larla doldurun
Contra

0

Bu temiz bir numara. Belirli bir değer aralığı arasında sayısal değerlerle uğraşıyorsanız, sürüm nesnesinin her düzeyine bir değer atayabilirsiniz. Örneğin, "en büyükDeğer" burada 0xFF olarak ayarlanmıştır, bu da sürümlemenize çok "IP" bir görünüm oluşturur.

Bu aynı zamanda alfa-sayısal versiyonlamayı da yönetir (yani 1.2a <1.2b)

// The version compare function
function compareVersion(data0, data1, levels) {
    function getVersionHash(version) {
        var value = 0;
        version = version.split(".").map(function (a) {
            var n = parseInt(a);
            var letter = a.replace(n, "");
            if (letter) {
                return n + letter[0].charCodeAt() / 0xFF;
            } else {
                return n;
            }
        });
        for (var i = 0; i < version.length; ++i) {
            if (levels === i) break;
            value += version[i] / 0xFF * Math.pow(0xFF, levels - i + 1);
        }
        return value;
    };
    var v1 = getVersionHash(data0);
    var v2 = getVersionHash(data1);
    return v1 === v2 ? -1 : v1 > v2 ? 0 : 1;
};
// Returns 0 or 1, correlating to input A and input B
// Direct match returns -1
var version = compareVersion("1.254.253", "1.254.253a", 3);

0

Gibi sürümünden itibaren @ mar10 , benim bakış itibaren, yanlış kullanımının bir şans var gerçi (sürüm ile uyumlu eğer durum böyle değil gibi görünüyor Semantik Sürüm belgesinde, ancak bazı "yapı numarası" kullanılırsa durumda olabilir ):

versionCompare( '1.09', '1.1');  // returns 1, which is wrong:  1.09 < 1.1
versionCompare('1.702', '1.8');  // returns 1, which is wrong: 1.702 < 1.8

Buradaki sorun, sürüm numarasının alt numaralarının, bazı durumlarda, bir sayının rasyonel kısmına benzer olan, sıfırdan kesilmiş olarak yazılmasıdır (en azından farklı yazılım kullanırken son zamanlarda gördüğüm gibi), bu yüzden:

5.17.2054 > 5.17.2
5.17.2 == 5.17.20 == 5.17.200 == ... 
5.17.2054 > 5.17.20
5.17.2054 > 5.17.200
5.17.2054 > 5.17.2000
5.17.2054 > 5.17.20000
5.17.2054 < 5.17.20001
5.17.2054 < 5.17.3
5.17.2054 < 5.17.30

Bununla birlikte, birinci (veya hem birinci hem de ikinci) sürüm alt numarası, her zaman gerçekte eşit olduğu bir tamsayı değeri olarak ele alınır.

Bu tür bir sürüm kullanıyorsanız, örnekte yalnızca birkaç satırı değiştirebilirsiniz:

// replace this:
p1 = parseInt(v1parts[i], 10);
p2 = parseInt(v2parts[i], 10);
// with this:
p1 = i/* > 0 */ ? parseFloat('0.' + v1parts[i], 10) : parseInt(v1parts[i], 10);
p2 = i/* > 0 */ ? parseFloat('0.' + v2parts[i], 10) : parseInt(v2parts[i], 10);

İlki hariç her alt numara bir float olarak karşılaştırılacak Yani, öylesine 09ve 1olacak 0.09ve 0.1buna göre ve düzgün bu şekilde karşılaştırıldı. 2054ve 3olacak 0.2054ve 0.3.

Bu durumda tam sürüm ( @ mar10'a aktarılır ):

/** Compare two dotted version strings (like '10.2.3').
 * @returns {Integer} 0: v1 == v2, -1: v1 < v2, 1: v1 > v2
 */
function versionCompare(v1, v2) {
    var v1parts = ("" + v1).split("."),
        v2parts = ("" + v2).split("."),
        minLength = Math.min(v1parts.length, v2parts.length),
        p1, p2, i;
    // Compare tuple pair-by-pair. 
    for(i = 0; i < minLength; i++) {
        // Convert to integer if possible, because "8" > "10".
        p1 = i/* > 0 */ ? parseFloat('0.' + v1parts[i], 10) : parseInt(v1parts[i], 10);;
        p2 = i/* > 0 */ ? parseFloat('0.' + v2parts[i], 10) : parseInt(v2parts[i], 10);
        if (isNaN(p1)){ p1 = v1parts[i]; } 
        if (isNaN(p2)){ p2 = v2parts[i]; } 
        if (p1 == p2) {
            continue;
        }else if (p1 > p2) {
            return 1;
        }else if (p1 < p2) {
            return -1;
        }
        // one operand is NaN
        return NaN;
    }
    // The longer tuple is always considered 'greater'
    if (v1parts.length === v2parts.length) {
        return 0;
    }
    return (v1parts.length < v2parts.length) ? -1 : 1;
}

PS Daha yavaştır, ancak dizenin aslında karakter dizisi olduğu gerçeğini çalıştıran aynı karşılaştırma işlevini yeniden kullanmayı düşünmek de mümkündür:

 function cmp_ver(arr1, arr2) {
     // fill the tail of the array with smaller length with zeroes, to make both array have the same length
     while (min_arr.length < max_arr.length) {
         min_arr[min_arr.lentgh] = '0';
     }
     // compare every element in arr1 with corresponding element from arr2, 
     // but pass them into the same function, so string '2054' will act as
     // ['2','0','5','4'] and string '19', in this case, will become ['1', '9', '0', '0']
     for (i: 0 -> max_length) {
         var res = cmp_ver(arr1[i], arr2[i]);
         if (res !== 0) return res;
     }
 }

0

Bunu Kons fikrine dayanarak yaptım ve Java sürümü "1.7.0_45" için optimize ettim. Sadece bir sürüm dizgisini bir kayan noktaya dönüştürmek için tasarlanmış bir işlevdir. Bu işlev:

function parseVersionFloat(versionString) {
    var versionArray = ("" + versionString)
            .replace("_", ".")
            .replace(/[^0-9.]/g, "")
            .split("."),
        sum = 0;
    for (var i = 0; i < versionArray.length; ++i) {
        sum += Number(versionArray[i]) / Math.pow(10, i * 3);
    }
    console.log(versionString + " -> " + sum);
    return sum;
}

"1.7.0_45" dizesi 1.0070000450000001 biçimine dönüştürülür ve bu normal bir karşılaştırma için yeterlidir. Hata burada açıklanır: JavaScript'te kayan nokta sayısı hassasiyeti ile nasıl başa çıkılır? . Herhangi bir parçada 3'ten fazla basamağa ihtiyacınız varsa bölücüyü değiştirebilirsinizMath.pow(10, i * 3); .

Çıktı şöyle görünecektir:

1.7.0_45         > 1.007000045
ver 1.7.build_45 > 1.007000045
1.234.567.890    > 1.23456789

0

Ben sürüm karşılaştırma aynı sorun vardı, ama muhtemelen bir şey içeren sürümleri ile (yani: nokta olmayan ayırıcılar, rc1, rc2 ... gibi uzantıları).

Temelde sürüm dizelerini sayılara ve sayı olmayan sayılara bölen ve türe göre karşılaştırmaya çalışan bunu kullandım.

function versionCompare(a,b) {
  av = a.match(/([0-9]+|[^0-9]+)/g)
  bv = b.match(/([0-9]+|[^0-9]+)/g)
  for (;;) {
    ia = av.shift();
    ib = bv.shift();
    if ( (typeof ia === 'undefined') && (typeof ib === 'undefined') ) { return 0; }
    if (typeof ia === 'undefined') { ia = '' }
    if (typeof ib === 'undefined') { ib = '' }

    ian = parseInt(ia);
    ibn = parseInt(ib);
    if ( isNaN(ian) || isNaN(ibn) ) {
      // non-numeric comparison
      if (ia < ib) { return -1;}
      if (ia > ib) { return 1;}
    } else {
      if (ian < ibn) { return -1;}
      if (ian > ibn) { return 1;}
    }
  }
}

Burada bazı durumlar için bazı varsayımlar vardır, örneğin: "1.01" === "1.1" veya "1.8" <"1.71". Anlamsal sürüm 2.0.0 tarafından belirtildiği gibi "1.0.0-rc.1" <"1.0.0" yönetilemiyor


0

Sürümlerin sıralamadan önce önişlenmesi, parseInt öğesinin gereksiz yere birden çok kez çağrılmadığı anlamına gelir. Michael Deal'ın önerisine benzer Array # haritasını kullanarak, standart bir 3 bölüm sömesterinin en yeni sürümünü bulmak için kullandığım bir tür:

var semvers = ["0.1.0", "1.0.0", "1.1.0", "1.0.5"];

var versions = semvers.map(function(semver) {
    return semver.split(".").map(function(part) {
        return parseInt(part);
    });
});

versions.sort(function(a, b) {
    if (a[0] < b[0]) return 1;
    else if (a[0] > b[0]) return -1;
    else if (a[1] < b[1]) return 1;
    else if (a[1] > b[1]) return -1;
    else if (a[2] < b[2]) return 1;
    else if (a[2] > b[2]) return -1;
    return 0;
});

var newest = versions[0].join(".");
console.log(newest); // "1.1.0"

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.