如何在javascript中对混合数字/字母数字数组进行排序

时间:2021-05-21 16:02:07

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?

但只能按字母/数字排序,直到组合1个数字和1个字符,如A1,A2,A10。但如果在这种情况下会有像A3A,A3B这样的值,它就不会排序。可以使用直接JavaScript或jQuery来完成吗?

4 个解决方案

#1


2  

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

注意:正则表达式(/.../i)中的i修饰符表示不区分大小写(查找小写和大写)。

#2


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

#3


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

#4


0  

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)

#1


2  

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

注意:正则表达式(/.../i)中的i修饰符表示不区分大小写(查找小写和大写)。

#2


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

#3


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

#4


0  

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)