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 09
ve 1
olacak 0.09
ve 0.1
buna göre ve düzgün bu şekilde karşılaştırıldı. 2054
ve 3
olacak 0.2054
ve 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;
}
}