phpjs
Version:
172 lines (144 loc) • 4.5 kB
Markdown
---
layout: page
title: "JavaScript strnatcasecmp function"
comments: true
sharing: true
footer: true
alias:
- /functions/view/strnatcasecmp:540
- /functions/view/strnatcasecmp
- /functions/view/540
- /functions/strnatcasecmp:540
- /functions/540
---
<!-- Generated by Rakefile:build -->
A JavaScript equivalent of PHP's strnatcasecmp
{% codeblock strings/strnatcasecmp.js lang:js https://raw.github.com/kvz/phpjs/master/functions/strings/strnatcasecmp.js raw on github %}
function strnatcasecmp (str1, str2) {
// From: http://phpjs.org/functions
// + 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;
}
// prevent possible infinite loop
if (ia >= a.length && ib >= b.length) return 0;
++ia;
++ib;
}
}
{% endcodeblock %}
- [Raw function on GitHub](https://github.com/kvz/phpjs/blob/master/functions/strings/strnatcasecmp.js)
Please note that php.js uses JavaScript objects as substitutes for PHP arrays, they are
the closest match to this hashtable-like data structure.
Please also note that php.js offers community built functions and goes by the
[McDonald's Theory](https://medium.com/what-i-learned-building/9216e1c9da7d). We'll put online
functions that are far from perfect, in the hopes to spark better contributions.
Do you have one? Then please just:
- [Edit on GitHub](https://github.com/kvz/phpjs/edit/master/functions/strings/strnatcasecmp.js)
### Example 1
This code
{% codeblock lang:js example %}
strnatcasecmp(10, 1);
strnatcasecmp('1', '10');
{% endcodeblock %}
Should return
{% codeblock lang:js returns %}
1
-1
{% endcodeblock %}
### Other PHP functions in the strings extension
{% render_partial _includes/custom/strings.html %}