1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
|
// Create global namespace
if(typeof(phpjs) === 'undefined')
phpjs = {};
phpjs.strnatcasecmp = function(str1, str2) {
// http://jsphp.co/jsphp/fn/view/strnatcasecmp
// + original by: Martin Pool
// + reimplemented by: Pierre-Luc Paour
// + reimplemented by: Kristof Coomans (SCK-CEN (Belgian Nucleair Research Centre))
// + reimplemented by: Brett Zamir (http://brett-zamir.me)
// + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// + input by: Devan Penner-Woelk
// + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// * example 1: strnatcasecmp(10, 1);
// * returns 1: 1
// * example 1: strnatcasecmp('1', '10');
// * returns 1: -1
var a = (str1 + '').toLowerCase();
var b = (str2 + '').toLowerCase();
var isWhitespaceChar = function (a) {
return a.charCodeAt(0) <= 32;
};
var isDigitChar = function (a) {
var charCode = a.charCodeAt(0);
return (charCode >= 48 && charCode <= 57);
};
var compareRight = function (a, b) {
var bias = 0;
var ia = 0;
var ib = 0;
var ca;
var cb;
// The longest run of digits wins. That aside, the greatest
// value wins, but we can't know that it will until we've scanned
// both numbers to know that they have the same magnitude, so we
// remember it in BIAS.
for (var cnt = 0; true; ia++, ib++) {
ca = a.charAt(ia);
cb = b.charAt(ib);
if (!isDigitChar(ca) && !isDigitChar(cb)) {
return bias;
} else if (!isDigitChar(ca)) {
return -1;
} else if (!isDigitChar(cb)) {
return 1;
} else if (ca < cb) {
if (bias === 0) {
bias = -1;
}
} else if (ca > cb) {
if (bias === 0) {
bias = 1;
}
} else if (ca === '0' && cb === '0') {
return bias;
}
}
};
var ia = 0,
ib = 0;
var nza = 0,
nzb = 0;
var ca, cb;
var result;
while (true) {
// only count the number of zeroes leading the last number compared
nza = nzb = 0;
ca = a.charAt(ia);
cb = b.charAt(ib);
// skip over leading spaces or zeros
while (isWhitespaceChar(ca) || ca === '0') {
if (ca === '0') {
nza++;
} else {
// only count consecutive zeroes
nza = 0;
}
ca = a.charAt(++ia);
}
while (isWhitespaceChar(cb) || cb === '0') {
if (cb === '0') {
nzb++;
} else {
// only count consecutive zeroes
nzb = 0;
}
cb = b.charAt(++ib);
}
// process run of digits
if (isDigitChar(ca) && isDigitChar(cb)) {
if ((result = compareRight(a.substring(ia), b.substring(ib))) !== 0) {
return result;
}
}
if (ca === '0' && cb === '0') {
// The strings compare the same. Perhaps the caller
// will want to call strcmp to break the tie.
return nza - nzb;
}
if (ca < cb) {
return -1;
} else if (ca > cb) {
return +1;
}
++ia;
++ib;
}
}
|