Implementing a Sort for an Array Yesterday, I gave an interview after a long time, and I was asked a question which I couldn't solve on the spot.

I had to implement a sort function for a Array of strings in JavaScript, with the following requirements:


The Array will always contain Strings
For sorting, Upper Case has higher priority than Lowe Case Letters, with Numbers having the Least.
Assume that Array.sort() cannot be used
The performance of the sorting is not a factor; i.e. Bubble sort is fine.


I was thinking of the solution today, and came up with this:



function sortArray(items) {
  let itemcount = items.length;
  for (var i = 0; i &lt; itemcount; i++) { //number of passes
    for (var j = 0; j &lt; (itemcount - 1 - i); j++) { //for checking all pairs in a given pass
      let a = items[j];
      let b = items[j + 1];
      if (compareCaseSenitiveStrings(a, b) &lt; 0) {
        console.log("Switch", a, b)
        items[j + 1] = a;
        items[j] = b;
      }
    }
  }
  //return
  return items;
}


//Function to compare two given strings, and return the index of the higher priority one
function compareCaseSenitiveStrings(a, b) {

  //Inner functions
  function compareCharacters(a, b) {
    //check the case first()
    if (a.getFirstCase() == b.getFirstCase()) {
      let charDiff = a.codePointAt(0) - b.codePointAt(0);
      return -Math.sign(charDiff)
    } else {
      //different cases
      //We need to pass the id of the one which is higher;
      let requiredCaseOrder = ["NONE", "LOWER", "UPPER"];
      return requiredCaseOrder.indexOf(a.getFirstCase()) - requiredCaseOrder.indexOf(b.getFirstCase());
    }
  }

  function isNumeric(n) {
      return !isNaN(parseFloat(n)) &amp;&amp; isFinite(n);
    }
    //End of inner functions
    //===============================================

  //Start of function here

  //First check if both are numbers
  if (isNumeric(a) &amp;&amp; isNumeric(b)) {
    //return the index of smaller number (since it has higher priority)
    return -Math.sign((parseFloat(a) - parseFloat(b)));
  }

  //Now check that lengths of both is greater than 0
  if ((a.length &gt; 0) &amp;&amp; (b.length &gt; 0)) {
    //check the first elements of this string
    let result = compareCharacters(a[0], b[0]);
    if (result != 0) {
      //this means one input has higher priority, lets return that
      return result;
    } else {
      //both are equal
      //get the result of remaining characters
      return compareCaseSenitiveStrings(a.substring(1), b.substring(1));
    }
  } else {
    //length of atleast one of these strings is zero.
    //return the index of the longer element
    let lengthDiff = a.length - b.length;
    return Math.sign(lengthDiff);
  }
}

String.prototype.getFirstCase = function() {
  let caseEnum = ["LOWER", "NONE", "UPPER"];
  var caseIndex = 1;
  if (this == this.toLowerCase()) {
    caseIndex--;
  }
  if (this == this.toUpperCase()) {
    caseIndex++;
  }
  return caseEnum[caseIndex];
};




Is this code readable enough? 
Are there any other Design Patterns that could be applied? Any other points which could be improved?
Sorting is hard.


console.log( sortArray([ '123', '9' , '1' , '11' ]) ); returns ["1", "9", "11", "123"], that does not sound good. After removing the numeric test I get ["11", "123", "1", "9"] which is better but not intuitive, I would have expected the 1 up front. This shows that you cannot just write the code, you need to build a set of tests to validate your code. Especially during interviews.
String.prototype.getFirstCase is very cute, but it needs commenting for lesser readers.
You are mixing var and let, I am not too excited about that
If you remove the numeric test, then you no longer need isNumeric as well
compareCaseSenitiveStrings should be compareCaseSensitiveStrings
I would convert 2 line comments to 1 line comment for readability, and an overall review of what comments really add value
Other than the code was very readable