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