Bagaimana cara membandingkan nomor versi perangkat lunak menggunakan js? (hanya angka)


164

Ini nomor versi perangkat lunak:

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

Bagaimana saya bisa membandingkan ini ?? Asumsikan urutan yang benar adalah:

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

Idenya sederhana ...: Baca digit pertama, daripada, yang kedua, setelah itu yang ketiga .... Tapi saya tidak bisa mengonversi nomor versi menjadi angka float .... Anda juga dapat melihat nomor versi seperti ini:

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

dan ini lebih jelas untuk melihat apa ide di balik ... Tapi, bagaimana cara mengubahnya menjadi program komputer ?? Adakah yang tahu bagaimana cara menyortir ini? Terima kasih.


5
Ini akan menjadi pertanyaan wawancara tipe fizzbuzz yang bagus.
Steve Claridge

2
Ini sebabnya semua nomor versi perangkat lunak harus bilangan bulat seperti 2001403. Bila Anda ingin menampilkannya dengan cara yang ramah seperti "2.0.14.3" maka Anda memformat nomor versi pada waktu presentasi.
jarmod

2
Masalah umum di sini adalah perbandingan Versi Semantik, dan ini tidak sepele (lihat # 11 di semver.org ). Untungnya, ada perpustakaan resmi untuk itu, versi semantik untuk npm .
Dan Dascalescu

1
Ditemukan skrip sederhana yang membandingkan semvers
vsync

Jawaban:


133

Ide dasar untuk membuat perbandingan ini adalah menggunakan Array.split untuk mendapatkan array bagian dari string input dan kemudian membandingkan pasangan bagian dari dua array; jika bagian tidak sama kita tahu versi mana yang lebih kecil.

Ada beberapa detail penting yang perlu diingat:

  1. Bagaimana bagian-bagian dalam setiap pasangan harus dibandingkan? Pertanyaannya ingin membandingkan secara numerik, tetapi bagaimana jika kita memiliki string versi yang tidak terdiri dari hanya digit (misalnya "1.0a")?
  2. Apa yang harus terjadi jika satu string versi memiliki lebih banyak bagian daripada yang lain? Kemungkinan besar "1.0" harus dianggap kurang dari "1.0.1", tetapi bagaimana dengan "1.0.0"?

Berikut kode untuk implementasi yang dapat Anda gunakan secara langsung ( intinya dengan dokumentasi ):

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;
}

Versi ini membandingkan bagian secara alami , tidak menerima sufiks karakter dan menganggap "1.7" lebih kecil dari "1.7.0". Mode perbandingan dapat diubah menjadi leksikografis dan string versi yang lebih pendek dapat secara otomatis diisi dengan nol menggunakan argumen ketiga opsional.

Ada JSFiddle yang menjalankan "unit test" di sini ; ini adalah versi yang sedikit diperluas dari karya ripper234 (terima kasih).

Catatan penting: Kode ini menggunakan Array.mapdan Array.every, yang berarti tidak akan berjalan dalam versi IE lebih awal dari 9. Jika Anda perlu mendukung mereka, Anda harus menyediakan polyfill untuk metode yang hilang.


16
Berikut ini adalah versi yang disempurnakan dengan beberapa tes unit: jsfiddle.net/ripper234/Xv9WL/28
ripper234

5
Hai Semua, saya sudah menggulirkan inti ini ke dalam gitrepo dengan tes dan segalanya dan meletakkannya di npm dan bower sehingga saya bisa memasukkannya dalam proyek saya lebih mudah. github.com/gabe0x02/version_compare
Gabriel Littman

2
@GabrielLittman: Hei, terima kasih telah meluangkan waktu untuk melakukan itu! Namun semua kode pada SO dilisensikan dengan CC-BY-SA secara default. Itu berarti Anda tidak dapat memiliki paket Anda berlisensi GPL. Saya tahu pengacara bukan untuk apa orang di sini, tetapi akan lebih baik jika Anda memperbaikinya.
Jon

2
@GabrielLittman: GPL sebenarnya sangat membatasi dalam arti bahwa Anda dipaksa untuk lisensi GPL semua kode yang bersentuhan dengan kode GPL yang ada. Pokoknya, untuk referensi di masa depan: lisensi "melakukan apa pun yang Anda inginkan, tanpa ikatan" yang baik dan banyak digunakan adalah MIT .
Jon

3
@GabrielLittman: sudah ada perpustakaan yang didirikan yang ditulis oleh para pengembang berpengalaman yang melakukan perbandingan semver.
Dan Dascalescu

82

semver

Parser versi semantik digunakan oleh npm.

instal semver $ npm

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, '*')

Tautan Versi Semantik :
https://www.npmjs.com/package/semver#prerelease-identifiers


8
Iya. Ini adalah jawaban yang benar - membandingkan versi adalah non-sepele (lihat # 11 di semver.org ), dan ada perpustakaan tingkat produksi yang melakukan pekerjaan itu.
Dan Dascalescu

7
secara teknis, ini bukan jawaban yang tepat, karena node.js dan javascript berbeda. Saya kira pertanyaan awal lebih ditujukan untuk browser. Tetapi google membawa saya ke sini dan untungnya saya menggunakan simpul :)
Lee Gary

2
NodeJS bukan hanya solusi sisi-server saja. Kerangka elektron menyematkan nodeJS untuk aplikasi desktop. Ini sebenarnya jawaban yang saya cari.
Anthony Raymond

2
semver ini adalah paket npm, dapat digunakan pada lingkungan JS apa saja! INI ADALAH jawaban yang tepat
neiker

4
@artuska baik maka cukup pergi untuk paket lain seperti semver-bandingkan - 233B (kurang dari 0,5 kB!) 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"));

Saya pikir baris: var len = Math.min(a_components.length, b_components.length);akan menyebabkan versi 2.0.1.1 dan 2.0.1 diperlakukan sama?
Jon Egerton

1
Tidak, lihat setelah loop! Jika satu string adalah awalan dari yang lain (yaitu loop mencapai akhir), maka yang lebih panjang diambil sebagai lebih tinggi.
Joe

Mungkin Anda menunda kesalahanku pada bahasa Inggris dalam komentar ...
Joe

@Joe saya tahu jawaban yang agak lama tapi saya menggunakan fungsinya. Menguji a = '7'dan b = '7.0'mengembalikan -1karena 7.0 lebih panjang. Ada saran untuk itu? ( console.log(compare("7", "7.0")); //returns -1)
RaphaelDDL

Saya kira itu datang di bawah judul perilaku yang tidak terdefinisi. Jika Anda memiliki nomor versi ini maka saya yakin Anda dapat memodifikasi logika agar sesuai dengan kebutuhan Anda.
Joe

48

Fungsi perbandingan yang sangat kecil, namun sangat cepat ini membutuhkan nomor versi dengan panjang berapa pun dan ukuran nomor apa pun per segmen .

Nilai
pengembalian : - angka < 0jika a <b
- angka > 0jika a> b
- 0jika a = b

Jadi Anda dapat menggunakannya sebagai fungsi perbandingan untuk Array.sort ();

EDIT: Versi Bugfixed menelanjangi angka nol untuk mengenali "1" dan "1.0.0" sebagai sama

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"]


Gagal dengan '0,0' dan '0,0.0'. Lihat biola: jsfiddle.net/emragins/9e9pweqg
emragins

1
@emragins Kapan Anda perlu melakukan itu?
Skylar Ittner

1
@emragins: Saya tidak melihat di mana ia gagal. Ini menghasilkan di ["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"] mana output kode Anda ["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"] , yang sama persis, karena 0,0 dan 0,0,0 dianggap sama , yang berarti tidak relevan apakah '0,0' sebelum '0,0,0' atau sebaliknya.
LeJared

Saya setuju ini adalah hal yang biasa. Saya menggunakan ini dengan github.com/jonmiles/bootstrap-treeview , yang tingkatan node dengan cara yang mirip dengan versi, hanya itu benar-benar hanya simpul orangtua / anak dan indeks mereka. Ex. Induk: 0.0, anak: 0.0.0, 0.0.1. Lihat masalah ini untuk detail lebih lanjut tentang mengapa saya peduli: github.com/jonmiles/bootstrap-treeview/issues/251
emragins

1
Lihat jawaban di sini stackoverflow.com/questions/6611824/why-do-we-need-to-use-radix . Browser lama digunakan untuk menebak parameter radix jika tidak ditentukan. Nol terdepan dalam string angka seperti bagian tengah dalam "1.09.12" digunakan untuk diuraikan dengan radix = 8 yang menghasilkan angka 0 dan bukan angka yang diharapkan 9.
LeJared

14

Diambil dari http://java.com/js/deployJava.js :

    // 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;
    }

Sederhana, tetapi terbatas pada tiga bidang versi.
Dan Dascalescu

11

Tidak dapat menemukan fungsi melakukan apa yang saya inginkan di sini. Jadi saya menulis sendiri. Ini kontribusi saya. Semoga ada yang berguna.

Pro:

  • Menangani string versi dengan panjang sewenang-wenang. '1' atau '1.1.1.1.1'.

  • Default setiap nilai ke 0 jika tidak ditentukan. Hanya karena sebuah string lebih panjang bukan berarti itu versi yang lebih besar. ('1' harus sama dengan '1.0' dan '1.0.0.0'.)

  • Bandingkan angka bukan string. ('3' <'21' harus benar. Tidak salah.)

  • Jangan buang waktu untuk membandingkan yang tidak berguna dalam loop. (Membandingkan dengan ==)

  • Anda dapat memilih pembanding sendiri.

Cons:

  • Itu tidak menangani huruf dalam string versi. (Aku tidak tahu bagaimana itu akan bekerja?)

Kode saya, mirip dengan jawaban yang diterima oleh Jon :

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);
}

Contoh :

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

versi ini menurut saya lebih baik daripada versi di jawaban yang disetujui!
user3807877

1
Fungsi ini rentan terhadap injeksi kode jika parameter pembanding digunakan dengan input pengguna yang tidak dicentang! Contoh: compareVersions ('1.2', '== 0; lansiran ("cotcha");', '1.2');
LeJared

@LeJared Benar. Ketika saya menulisnya, kami tidak akan menggunakannya dengan kode yang dikirimkan pengguna. Mungkin membawanya sebagai penipu mungkin. Saya sekarang telah memperbarui kode untuk menghilangkan kemungkinan itu. Namun sekarang, ketika webpack dan bundler node.js lainnya menjadi lazim, saya menyarankan bahwa jawaban Mohammed Akdim di atas, menggunakan semver, hampir selalu menjadi jawaban yang benar untuk pertanyaan ini.
Viktor

10

Fungsi sederhana dan pendek:

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
}

Tes:

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

Anda dapat menyederhanakannya dengan: const a = ~~ newParts [i]; Sebenarnya ini adalah cara paling efisien untuk mengubah string menjadi integer, yang mengembalikan 0 jika variabel tidak terdefinisi atau mengandung karakter non-numerik.
vanowm

5

Maafkan saya jika ide ini sudah dikunjungi di tautan yang belum saya lihat.

Saya telah berhasil dengan konversi bagian menjadi jumlah tertimbang seperti:

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);

Yang membuat perbandingan sangat mudah (membandingkan ganda). Bidang versi kami tidak pernah lebih dari 4 digit.

7.10.2.184  -> 7010002184.0
7.11.0.1385 -> 7011001385.0

Saya harap ini membantu seseorang, karena beberapa persyaratan tampak sedikit berlebihan.


2
Ini akan pecah, jika this.minor> 999 (akan tumpang tindih dengan mayor)
Afanasii Kurakin

5

Berikut ini adalah versi pendek lain yang berfungsi dengan sejumlah sub versi, angka nol dan bahkan angka dengan huruf (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;
}

Keluaran:

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 jawaban:

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;
    }

Kode paling sederhana untuk peramban modern:

 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;
 }

Idenya di sini adalah untuk membandingkan angka tetapi dalam bentuk string. untuk membuat perbandingan berfungsi, kedua string harus memiliki panjang yang sama. begitu:

"123" > "99" menjadi "123" > "099"
padding nomor pendek "perbaiki" perbandingan

Di sini saya mengisi setiap bagian dengan nol dengan panjang 10. Kemudian gunakan string sederhana untuk membandingkan jawabannya

Contoh:

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

maukah Anda menjelaskan fungsi compareVersion2apa yang sebenarnya terjadi?
Usman Wali

Bagus, maka Anda dapat menggunakan substringbukan padStartuntuk kompatibilitas yang lebih baik yaitu var zeros = "0000000000"; '0.2.32'.split('.').map( s => zeros.substring(0, zeros.length-s.length) + s ).join('.') akan memberi Anda 0000000000.0000000002.0000000032:)
Usman Wali


4

Jawaban verbose saya kurang dari sebagian besar jawaban di sini

/**
 * 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
Anda harus menjadikannya modul dan meletakkannya di node.js. sampai saat itu, saya mencuri kode Anda dengan atribusi kepada Anda. Terima kasih untuk ini.
r3wt

3

Meskipun pertanyaan ini sudah banyak jawaban, masing-masing mempromosikan solusi halaman belakang mereka sendiri, sementara kami memiliki seluruh ekosistem perpustakaan (pertempuran) yang teruji untuk ini.

Pencarian cepat pada NPM , GitHub , X akan memberi kita beberapa lib yang indah, dan saya ingin menjalankan beberapa:

semver-compareadalah lib yang sangat ringan (~ 230B) yang sangat berguna jika Anda ingin mengurutkan berdasarkan nomor versi, karena metode pustaka yang terbuka mengembalikan -1, 0atau secara 1tepat.

Inti dari lib:

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 ukurannya lumayan besar (~ 4.4kB gzipped), tetapi memungkinkan untuk beberapa perbandingan unik yang bagus seperti menemukan min / max dari tumpukan versi atau untuk mengetahui apakah versi yang disediakan unik atau kurang dari apa pun dalam koleksi versi.

compare-versionsadalah lib kecil lainnya (~ 630B gzipped) dan mengikuti spec dengan baik, artinya Anda dapat membandingkan versi dengan flag alpha / beta dan bahkan wildcard (seperti untuk versi minor / patch: 1.0.xatau1.0.* )

Intinya: tidak selalu perlu menyalin-menempelkan kode dari StackOverflow, jika Anda dapat menemukan versi yang layak, (unit-) yang diuji melalui manajer paket pilihan Anda.


3

Saya menghadapi masalah yang sama, dan saya sudah membuat solusi untuk itu. Jangan ragu untuk mencobanya.

Ini mengembalikan 0untuk equal, 1jika versi greaterdan -1jika ituless

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

Idenya adalah membandingkan dua versi dan tahu mana yang terbesar. Kami menghapus "." dan kami membandingkan setiap posisi vektor dengan yang lain.

// 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;
      }
   }
}

Jawaban epik, persis apa yang saya cari.
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
Selamat datang di SO. Pertanyaan ini sudah memiliki banyak jawaban bagus, tolong jangan menambahkan jawaban baru kecuali Anda menambahkan sesuatu yang baru.
ext

1

The replace()Fungsi hanya menggantikan kejadian pertama dalam string. Jadi, mari kita ganti .dengan ,. Setelah itu hapus semua .dan buat, untuk .lagi dan mengurai mengapung.

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

akhirnya, urutkan:

versions.sort();

1

Lihat posting blog ini . Fungsi ini berfungsi untuk nomor versi numerik.

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

Jika, misalnya, kami ingin memeriksa apakah versi jQuery saat ini kurang dari 1,8, parseFloat($.ui.version) < 1.8 )akan memberikan hasil yang salah jika versi "1.10.1", karena parseFloat ("1.10.1") kembali 1.1. Perbandingan string juga akan salah, karena "1.8" < "1.10"dievaluasi menjadifalse .

Jadi kita perlu tes seperti ini

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

Fungsi berikut menangani ini dengan benar:

/** 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;
}

Berikut ini beberapa contohnya:

// 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);

Lihat di sini untuk contoh langsung dan rangkaian tes: http://jsfiddle.net/mar10/8KjvP/


arghh, baru saja perhatikan bahwa ripper234 telah memposting URL biola di atas komentar beberapa bulan yang lalu yang sangat mirip. Ngomong-ngomong, saya menyimpan jawaban saya di sini ...
Maret

Yang ini juga akan gagal (karena sebagian besar varian sekitar) dalam kasus ini: versionCompare ('1.09', '1.1') mengembalikan "1", cara yang sama seperti versionCompare ('1.702', '1.8').
shaman.sir

Kode mengevaluasi "1.09"> "1.1" dan "1.702"> "1.8", yang saya pikir benar. Jika Anda tidak setuju: dapatkah Anda menunjukkan beberapa sumber yang mendukung pendapat Anda?
mar10

Itu tergantung pada prinsip Anda - karena saya tahu tidak ada aturan ketat atau sesuatu. Mengenai sumber daya, artikel wikipedia untuk "Versi perangkat lunak" dalam "Urutan yang bertambah" mengatakan bahwa 1,81 mungkin merupakan versi minor dari 1,8, jadi 1,8 harus dibaca sebagai 1,80. Artikel versi semantik semver.org/spec/v2.0.0.html juga mengatakan bahwa 1.9.0 -> 1.10.0 -> 1.11.0, jadi 1.9.0 diperlakukan sebagai 1.90.0 dibandingkan seperti ini. Jadi, mengikuti logika ini, versi 1.702 sebelum versi 1.8, yang diperlakukan sebagai 1.800.
shaman.sir

1
Saya melihat bahwa beberapa aturan berlaku 1,8 <1,81 <1,9. Tetapi dalam semver Anda akan menggunakan 1.8.1 bukannya 1.81. Semver (seperti yang saya mengerti) didefinisikan berdasarkan asumsi bahwa penambahan bagian akan selalu menghasilkan versi 'nanti', jadi 1,8 <1,8.1 <1,9 <1,10 <1,81 <1,81 <1,00 <1,100. Saya juga tidak melihat indikasi bahwa ini dibatasi hingga dua digit. Jadi saya akan mengatakan bahwa kode saya sepenuhnya sesuai dengan semver.
mar10

1

Berikut adalah implementasi naskah kopi yang cocok untuk digunakan dengan Array.sort yang terinspirasi oleh jawaban lain di sini:

# 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

Ini terinspirasi oleh jawaban LeJared .
Dan Dascalescu

ini tidak berfungsi dengan baik .. inilah hasilnya .. hasil ['1.1.1', '2.1.1', '3.3.1.0', '3.1.1.0']
ertan2002

1

Saya menulis modul simpul untuk menyortir versi, Anda dapat menemukannya di sini: version-sort

Fitur :

  • tidak ada batas urutan '1.0.1.5.53.54654.114.1.154.45' berfungsi
  • tidak ada batas panjang urutan: '1.1546515465451654654654654138754431574364321353734' karya
  • dapat mengurutkan objek berdasarkan versi (lihat README)
  • tahapan (seperti alpha, beta, rc1, rc2)

Jangan ragu untuk membuka masalah jika Anda membutuhkan fitur lain.


1

Ini berfungsi untuk versi numerik dari panjang mana pun yang dipisahkan oleh titik. Ia mengembalikan true hanya jika myVersion adalah> = minimumVersion, membuat asumsi bahwa versi 1 kurang dari 1.0, versi 1.1 kurang dari 1.1.0 dan seterusnya. Seharusnya cukup sederhana untuk menambahkan kondisi tambahan seperti menerima angka (hanya mengkonversi ke string) dan heksadesimal atau membuat pembatas dinamis (cukup tambahkan parameter pembatas kemudian ganti "." Dengan param)

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);
}

Berikut ini beberapa tes:

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"));

Atau di sini adalah versi rekursif

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

Saya menemukan cara paling sederhana untuk membandingkannya, tidak yakin apakah itu yang Anda inginkan. ketika saya menjalankan kode di bawah ini di konsol, itu masuk akal, dan menggunakan metode sort (), saya bisa mendapatkan array yang diurutkan dari string versi. ini didasarkan pada urutan abjad.

"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
Ini tidak berfungsi dengan baik untuk nomor versi dua digit, misalnya, 1.10.0.
Leukipp

1

Anda bisa menggunakannya String#localeComparebersamaoptions

kepekaan

Perbedaan mana dalam string harus mengarah pada nilai hasil yang tidak nol. Nilai yang mungkin adalah:

  • "base": Hanya string yang berbeda dalam huruf dasar yang dibandingkan sebagai tidak sama. Contoh: a ≠ b, a = á,a = A .
  • "accent": Hanya string yang berbeda dalam huruf atau aksen dasar dan tanda diakritik lainnya yang dibandingkan sebagai tidak sama. Contoh: a ≠ b, a ≠ á, a = A.
  • "case": Hanya string yang berbeda dalam huruf atau kasus dasar yang dibandingkan sebagai tidak setara. Contoh: a ≠ b, a = á, a ≠ A.
  • "variant": String yang berbeda dalam huruf dasar, aksen, dan tanda diakritik lainnya, atau perbandingan kasus sebagai tidak sama. Perbedaan lain juga dapat dipertimbangkan. Contoh: a ≠ b, a ≠ á, a ≠ A.

Standarnya adalah "varian" untuk "sort" penggunaan; itu tergantung lokal untuk penggunaan "pencarian".

numerik

Apakah pengumpulan numerik harus digunakan, sehingga "1" <"2" <"10". Nilai yang mungkin adalah truedan false; standarnya adalah false. Opsi ini dapat diatur melalui properti opsi atau melalui kunci ekstensi Unicode; jika keduanya disediakan, optionsproperti diutamakan. Implementasi tidak diperlukan untuk mendukung properti ini.

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);


Bagaimana cara kerjanya? Apa yang di undefinedatas, Bahasa? Kenapa Anda bisa memposting ini sementara saya membaca yang lain;)
mplungjan

undefinedadalah bagian locales, tidak digunakan di sini.
Nina Scholz

0

tidak bisakah Anda mengonversinya menjadi angka dan kemudian mengurutkan setelah ukuran? Tambahkan angka 0 ke angka yang panjangnya <4

bermain-main di konsol:

$(["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  )
});

semakin besar versinya, semakin besar jumlahnya. Sunting: mungkin perlu disesuaikan ke akun untuk seri versi yang lebih besar


Itu hanya contoh, karena dia harus melakukan beberapa hal sendiri: P Alih-alih 4, dapatkan jumlah angka yang dimiliki versi terbesar, lalu isi yang lebih rendah dari itu dengan 0's
Contra

0

Ini adalah trik yang rapi. Jika Anda berurusan dengan nilai numerik, di antara rentang nilai tertentu, Anda dapat menetapkan nilai untuk setiap level objek versi. Misalnya "Nilai terbesar" diatur ke 0xFF di sini, yang menciptakan semacam tampilan "IP" untuk versi Anda.

Ini juga menangani versi alpha-numeric (yaitu 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

Saya suka versi dari @ mar10 , meskipun dari sudut pandang saya, ada kemungkinan kesalahan penggunaan (sepertinya tidak demikian jika versi kompatibel dengan dokumen Semantic Versioning , tetapi mungkin demikian halnya jika beberapa "nomor build" digunakan ):

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

Masalahnya di sini adalah bahwa sub-nomor nomor versi, dalam beberapa kasus, ditulis dengan nol trailing cut out (setidaknya seperti yang baru-baru ini saya lihat saat menggunakan perangkat lunak yang berbeda), yang mirip dengan bagian rasional dari angka, jadi:

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

Sub-nomor versi pertama (atau keduanya pertama dan kedua), bagaimanapun, selalu diperlakukan sebagai nilai integer yang sebenarnya sama dengan.

Jika Anda menggunakan versi semacam ini, Anda dapat mengubah beberapa baris saja dalam contoh:

// 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);

Jadi setiap sub-angka kecuali yang pertama akan dibandingkan sebagai float, jadi 09dan 1akan menjadi 0.09dan 0.1sesuai dan dibandingkan dengan benar dengan cara ini. 2054dan 3akan menjadi 0.2054dan 0.3.

Versi lengkapnya adalah (kredit ke @ mar10 ):

/** 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 Ini lebih lambat, tetapi juga mungkin untuk berpikir tentang menggunakan kembali fungsi perbandingan yang sama yang mengoperasikan fakta bahwa string sebenarnya adalah array karakter:

 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

Saya membuat ini berdasarkan ide Kons, dan dioptimalkan untuk versi Java "1.7.0_45". Itu hanya fungsi yang dimaksudkan untuk mengubah string versi menjadi float. Ini fungsinya:

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;
}

String "1.7.0_45" dikonversi ke 1.0070000450000001 dan ini cukup baik untuk perbandingan normal. Kesalahan dijelaskan di sini: Bagaimana cara menangani presisi angka floating point dalam JavaScript? . Jika membutuhkan lebih dari 3 digit pada bagian mana pun Anda dapat mengubah pembagiMath.pow(10, i * 3); .

Output akan terlihat seperti ini:

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

0

Saya memiliki masalah perbandingan versi yang sama, tetapi dengan versi yang mungkin mengandung apa pun (yaitu: pemisah yang bukan titik, ekstensi seperti rc1, rc2 ...).

Saya menggunakan ini, yang pada dasarnya membagi string versi menjadi angka dan bukan angka, dan mencoba membandingkannya dengan tipenya.

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;}
    }
  }
}

Ada beberapa asumsi di sini untuk beberapa kasus, misalnya: "1.01" === "1.1", atau "1,8" <"1,71". Gagal mengelola "1.0.0-rc.1" <"1.0.0", seperti yang ditentukan oleh Semantic versi 2.0.0


0

Memproses ulang versi sebelum pengurutan berarti parseInt tidak dipanggil beberapa kali secara tidak perlu. Menggunakan peta Array yang mirip dengan saran Michael Deal, berikut adalah jenis yang saya gunakan untuk menemukan versi terbaru dari semver 3 bagian standar:

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"

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.