8

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?

2
  • @RameshRajendran That's not a valid excuse for an off-topic question, this is indeed on-topic and a good question. It doesn't matter if this is a homework question or not. The user put forth a clear goal and output, along with that an attempted solution. That's much better then most the questions I see here. Commented Feb 1, 2017 at 6:02
  • @RameshRajendran This is actually a very good question. It should be protected instead of closed. Commented Feb 1, 2017 at 6:03

4 Answers 4

5

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).

Sign up to request clarification or add additional context in comments.

2 Comments

The output mismatch with what is OP exceptation ` "A1", "A3A", "A3B", "A3", `
@RameshRajendran I fixed it.
0

Try this functionality. it give the result which you want exactly

   var arr = ['A1', 'A10', 'A11', 'A12', 'A3A', 'A3B', 'A3', 'A4', 'B10', 'B2', 'F1', '1', '2', 'F3'];
function sortFn(a, b) {     
    var ax = [], bx = [];
    a.replace(/(\d+)|(\D+)/g, function(_, $1, $2) { ax.push([$1 || Infinity, $2 || ""]) });
    b.replace(/(\d+)|(\D+)/g, function(_, $1, $2) { bx.push([$1 || Infinity, $2 || ""]) });        
    while(ax.length && bx.length) {
        var an = ax.shift();
        var bn = bx.shift();
        var nn = (an[0] - bn[0]) || an[1].localeCompare(bn[1]);
        if(nn) return nn;
    }
    return ax.length - bx.length;      
}
console.log(arr.sort(sortFn));

Comments

0

You could sort it with splitted array by type and check for equality first and then by type.

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

array.sort(function (a, b) {
    var isNumber = function (v) { return (+v).toString() === v; },
        aa = a.match(/\d+|\D+/g),
        bb = b.match(/\d+|\D+/g),
        i = 0,
        l = Math.min(aa.length, bb.length);

    while (i < l && aa[i] === bb[i]) {
        i++;
    }
    if (i === l) {
        return aa.length - bb.length;
    }
    if (isNumber(aa[i]) && isNumber(bb[i])) {
        return aa[i] - bb[i];
    }
    return aa[i].localeCompare(bb[i]);
});

console.log(array);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Comments

-1
var a=[ {
    "LIST": "14:NATURAL RESOURCES"
},
{
    "LIST": "7:DIVERSITY IN LIVING ORGANISMS"
},
{
    "LIST": "3:ATOMS AND MOLECULES"
},
{
    "LIST": "10:GRAVITATION"
},
{
    "LIST": "6:TISSUES"
}]

var c=a.sort(function(a,b){
let aa=a.LIST,bb=b.LIST;
return parseInt(aa.split(":")[0] - bb.split(":")[0])

})

console.log(c)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.