मुझे @ mar10 से संस्करण पसंद है , हालांकि मेरे दृष्टिकोण से, गलतफहमी का एक मौका है (ऐसा लगता है कि यह संस्करण नहीं है यदि संस्करण सिमेंटिक संस्करण दस्तावेज़ के साथ संगत हैं , लेकिन मामला हो सकता है यदि कुछ "बिल्ड नंबर" का उपयोग किया जाता है ):
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
यहाँ समस्या यह है कि संस्करण संख्या की उप-संख्याएँ हैं, कुछ मामलों में, अनुगामी शून्य के कट आउट के साथ लिखा गया है (कम से कम जैसा कि मैं हाल ही में विभिन्न सॉफ़्टवेयर का उपयोग करते समय इसे देखता हूं), जो संख्या के तर्कसंगत भाग के समान है, इसलिए:
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
पहला (या दोनों पहला और दूसरा) संस्करण उप-संख्या, हालांकि, हमेशा पूर्णांक मान के रूप में माना जाता है जो वास्तव में इसके बराबर होता है।
यदि आप इस तरह के संस्करण का उपयोग करते हैं, तो आप उदाहरण में कुछ पंक्तियों को बदल सकते हैं:
// 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);
तो पहले एक को छोड़कर हर उप नंबर एक नाव के रूप में की तुलना में किया जाएगा, ताकि 09
और 1
बन जाएगा 0.09
और 0.1
तदनुसार और ठीक से इस तरह की तुलना में। 2054
और 3
हो जाएगा 0.2054
और 0.3
।
पूरा संस्करण तब है, ( @ 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;
}
पुनश्च यह धीमी है, लेकिन यह भी संभव है कि एक ही तुलना करने वाले फ़ंक्शन का पुनः उपयोग करने पर विचार करें कि इस तथ्य को संचालित करने के लिए कि स्ट्रिंग वास्तव में पसंद की सरणी है:
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;
}
}