Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to sort mixed numeric/alphanumeric array in javascript

I have a mixed array that I need to sort by number, alphabet and then by digit-

['A1', 'A10', 'A11', 'A12', 'A3A', 'A3B', 'A3', 'A4', 'B10', 'B2', 'F1', '1', '2', 'F3']

how do I sort it to be like:

['1', '2', 'A1', 'A2', 'A3', 'A3A', 'A3B', 'A4', 'A10', 'A11', 'A12', 'B2', 'B10', 'F1', 'F3']

Here is what I tried:

var reA = /[^a-zA-Z]/g;
var reN = /[^0-9]/g;
function sortAlphaNum(a, b) {
    var AInt = parseInt(a.Field, 10);
    var BInt = parseInt(b.Field, 10);

    if (isNaN(AInt) && isNaN(BInt)) {
        var aA = (a.Field).replace(reA, "");
        var bA = (b.Field).replace(reA, "");
        if (aA === bA) {
            var aN = parseInt((a.Field).replace(reN, ""), 10);
            var bN = parseInt((b.Field).replace(reN, ""), 10);
            return aN === bN ? 0 : aN > bN ? 1 : -1;
        } else {
            return aA > bA ? 1 : -1;
        }
    } else if (isNaN(AInt)) {//A is not an Int
        return 1;//to make alphanumeric sort first return -1 here
    } else if (isNaN(BInt)) {//B is not an Int
        return -1;//to make alphanumeric sort first return 1 here
    } else {
        return AInt > BInt ? 1 : -1;
    }
}

fieldselecteddata.sort(sortAlphaNum);

but that only sorts it alphabetically/numeric till combination of 1 numeric and 1 character like A1, A2, A10. But if there will be values like A3A, A3B in that case it wont sort properly. Can this be done with either straight JavaScript or jQuery?

like image 835
raj yadav Avatar asked Feb 01 '17 05:02

raj yadav


1 Answers

var arr = ['A1', 'A10', 'A11', 'A12', 'A3A', 'A3B', 'A3', 'A4', 'B10', 'B2', 'F1', '1', '2', 'F3'];

// regular expression to get the alphabetic and the number parts, if any
var regex = /^([a-z]*)(\d*)/i;

function sortFn(a, b) {
  var _a = a.match(regex);
  var _b = b.match(regex);

  // if the alphabetic part of a is less than that of b => -1
  if (_a[1] < _b[1]) return -1;
  // if the alphabetic part of a is greater than that of b => 1
  if (_a[1] > _b[1]) return 1;

  // if the alphabetic parts are equal, check the number parts
  var _n = parseInt(_a[2]) - parseInt(_b[2]);
  if(_n == 0) // if the number parts are equal start a recursive test on the rest
      return sortFn(a.substr(_a[0].length), b.substr(_b[0].length));
  // else, just sort using the numbers parts
  return _n;
}

console.log(arr.sort(sortFn));

Note: the i modifier in the regular expression (/.../i) means case-insensitive (looks for both lowercases and uppercases).

like image 64
ibrahim mahrir Avatar answered Sep 28 '22 04:09

ibrahim mahrir