关于javascript:排序混合的字母/数字数组

Sort mixed alpha/numeric array

我有一个混合数组,我需要先按字母然后按数字排序

1
[A1, A10, A11, A12, A2, A3, A4, B10, B2, F1, F12, F3]

我如何将其排序为:

1
[A1, A2, A3, A4, A10, A11, A12, B2, B10, F1, F3, F12]

我努力了

1
arr.sort(function(a,b) {return a - b});

但这只是按字母顺序排序。
可以使用直接的JavaScript或jQuery完成此操作吗?


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var reA = /[^a-zA-Z]/g;
var reN = /[^0-9]/g;

function sortAlphaNum(a, b) {
  var aA = a.replace(reA,"");
  var bA = b.replace(reA,"");
  if (aA === bA) {
    var aN = parseInt(a.replace(reN,""), 10);
    var bN = parseInt(b.replace(reN,""), 10);
    return aN === bN ? 0 : aN > bN ? 1 : -1;
  } else {
    return aA > bA ? 1 : -1;
  }
}
console.log(
["A1","A10","A11","A12","A2","A3","A4","B10","B2","F1","F12","F3"].sort(sortAlphaNum)
)


1
const sortAlphaNum = (a, b) => a.localeCompare(b, 'en', { numeric: true })`

用法:

1
2
const sortAlphaNum = (a, b) => a.localeCompare(b, 'en', { numeric: true })
console.log(['A1', 'A10', 'A11', 'A12', 'A2', 'A3', 'A4', 'B10', 'B2', 'F1', 'F12', 'F3'].sort(sortAlphaNum))

得到:

["A1","A2","A3","A4","A10","A11","A12","B2","B10","F1","F3","F12"]

您可能必须将'en'参数更改为您的语言环境或以编程方式确定,但这适用于英语字符串。

另外,localeCompare也不受超级一致支持,但是如果您使用babel进行转译不会有问题


我也遇到类似的情况,但是混合使用字母数字和数字,因此需要先对所有数字进行排序,然后再对字母数字进行排序,因此:

1
2
3
4
5
6
7
A10
1
5
A9
2
B3
A2

需要成为:

1
2
3
4
5
6
7
1
2
5
A2
A9
A10
B3

我能够使用提供的算法并对它进行更多修改以实现此目的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
var reA = /[^a-zA-Z]/g;
var reN = /[^0-9]/g;
function sortAlphaNum(a,b) {
    var AInt = parseInt(a, 10);
    var BInt = parseInt(b, 10);

    if(isNaN(AInt) && isNaN(BInt)){
        var aA = a.replace(reA,"");
        var bA = b.replace(reA,"");
        if(aA === bA) {
            var aN = parseInt(a.replace(reN,""), 10);
            var bN = parseInt(b.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;
    }
}
var newlist = ["A1", 1,"A10","A11","A12", 5, 3, 10, 2,"A2","A3","A4","B10","B2","F1","F12","F3"].sort(sortAlphaNum);


一种简单的方法是使用JavaScript https://www.w3schools.com/jsref/jsref_localecompare.asp的localeCompare()方法。

例:

1
2
3
4
5
6
7
export const sortAlphaNumeric = (a, b) => {
    // convert to strings and force lowercase
    a = typeof a === 'string' ? a.toLowerCase() : a.toString();
    b = typeof b === 'string' ? b.toLowerCase() : b.toString();

    return a.localeCompare(b);
};

预期行为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
1000X Radonius Maximus
10X Radonius
200X Radonius
20X Radonius
20X Radonius Prime
30X Radonius
40X Radonius
Allegia 50 Clasteron
Allegia 500 Clasteron
Allegia 50B Clasteron
Allegia 51 Clasteron
Allegia 6R Clasteron
Alpha 100
Alpha 2
Alpha 200
Alpha 2A
Alpha 2A-8000
Alpha 2A-900
Callisto Morphamax
Callisto Morphamax 500
Callisto Morphamax 5000
Callisto Morphamax 600
Callisto Morphamax 6000 SE
Callisto Morphamax 6000 SE2
Callisto Morphamax 700
Callisto Morphamax 7000
Xiph Xlater 10000
Xiph Xlater 2000
Xiph Xlater 300
Xiph Xlater 40
Xiph Xlater 5
Xiph Xlater 50
Xiph Xlater 500
Xiph Xlater 5000
Xiph Xlater 58


这可以做到:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function parseItem (item) {
  const [, stringPart = '', numberPart = 0] = /(^[a-zA-Z]*)(\d*)$/.exec(item) || [];
  return [stringPart, numberPart];
}

function sort (array) {
  return array.sort((a, b) => {
    const [stringA, numberA] = parseItem(a);
    const [stringB, numberB] = parseItem(b);
    const comparison = stringA.localeCompare(stringB);
    return comparison === 0 ? Number(numberA) - Number(numberB) : comparison;
  });
}

console.log(sort(['A1', 'A10', 'A11', 'A12', 'A2', 'A3', 'A4', 'B10', 'B2', 'F1', 'F12', 'F3']))
console.log(sort(['a25b', 'ab', 'a37b']))


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var a1 =["A1","A10","A11","A12","A2","A3","A4","B10","B2","F1","F12","F3"];

var a2 = a1.sort(function(a,b){
    var charPart = [a.substring(0,1), b.substring(0,1)],
        numPart = [a.substring(1)*1, b.substring(1)*1];

    if(charPart[0] < charPart[1]) return -1;
    else if(charPart[0] > charPart[1]) return 1;
    else{ //(charPart[0] == charPart[1]){
        if(numPart[0] < numPart[1]) return -1;
        else if(numPart[0] > numPart[1]) return 1;
        return 0;
    }
});

$('#r').html(a2.toString())

http://jsfiddle.net/8fRsD/


上述给定解决方案的唯一问题是,当数字数据相同且字母变化时,例如,逻辑失败。 28AB,28PQR,28HBC。
这是修改后的代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
var reA = /[^a-zA-Z]/g;
    var reN = /[^0-9]/g;
    var AInt = parseInt(a, 10);
    var BInt = parseInt(b, 10);
    if(isNaN(AInt) && isNaN(BInt)){
        var aA = a.replace(reA,"");
        var bA = b.replace(reA,"");
        if(aA === bA) {
            var aN = parseInt(a.replace(reN,""), 10);
            var bN = parseInt(b.replace(reN,""), 10);
            alert("in if"+aN+" :"+bN);
            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 if(AInt == BInt) {
        var aA = a.replace(reA,"");
        var bA = b.replace(reA,"");
        return aA > bA ? 1 : -1;
    }
    else {
        return AInt > BInt ? 1 : -1;
    }


您可以使用Intl.Collator

localeCompare相比,它具有性能优势。

浏览器可比性(所有浏览器都支持)

1
2
3
4
5
let arr = ["A1","A10","A11","A12","A2","A3","A4","B10","B2","F1","F12","F3"]

let op = arr.sort(new Intl.Collator('en',{numeric:true, sensitivity:'accent'}).compare)

console.log(op)


添加到epascarello接受的答案中,因为我无法对此发表评论。我还是一个菜鸟。
当其中一个strinng没有数字时,原始答案将无效。例如,A和A10不会按该顺序排序。因此,在这种情况下,您可能想跳回正常排序。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var reA = /[^a-zA-Z]/g;
var reN = /[^0-9]/g;
function sortAlphaNum(a,b) {
    var aA = a.replace(reA,"");
    var bA = b.replace(reA,"");
    if(aA === bA) {
      var aN = parseInt(a.replace(reN,""), 10);
      var bN = parseInt(b.replace(reN,""), 10);
      if(isNaN(bN) || isNaN(bN)){
        return  a > b ? 1 : -1;
      }
      return aN === bN ? 0 : aN > bN ? 1 : -1;
    } else {
     return aA > bA ? 1 : -1;
    }
 }
 ["A1","A10","A11","A12","A2","A3","A4","B10","B2","F1","F12","F3"].sort(sortAlphaNum);`

这是此答案的ES6 Typescript升级。

1
2
3
4
5
6
7
8
9
10
11
12
export function SortAlphaNum(a: string, b: string) {
const reA = /[^a-zA-Z]/g;
const reN = /[^0-9]/g;
const aA = a.replace(reA,"");
const bA = b.replace(reA,"");
if (aA === bA) {
    const aN = parseInt(a.replace(reN,""), 10);
    const bN = parseInt(b.replace(reN,""), 10);
    return aN === bN ? 0 : aN > bN ? 1 : -1;
} else {
    return aA > bA ? 1 : -1;
}

}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
alphaNumericCompare(a, b) {

    let 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) {
       let an = ax.shift();
       let bn = bx.shift();
       let nn = (an[0] - bn[0]) || an[1].localeCompare(bn[1]);
       if (nn) {
         return nn;
       }
     }
     return ax.length - bx.length;
}


我已经使用以下脚本解决了上述排序问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
arrVals.sort(function(a, b){
    //return b.text - a.text;
    var AInt = parseInt(a.text, 10);
    var BInt = parseInt(b.text, 10);

    if ($.isNumeric(a.text) == false && $.isNumeric(b.text) == false) {
        var aA = a.text
        var bA = b.text;
        return aA > bA ? 1 : -1;
    } else if ($.isNumeric(a.text) == false) {  // A is not an Int
        return 1;    // to make alphanumeric sort first return -1 here
    } else if ($.isNumeric(b.text) == false) {  // B is not an Int
        return -1;   // to make alphanumeric sort first return 1 here
    } else {
        return AInt < BInt ? 1 : -1;
    }
});

这对于混合良好的阵列效果很好。

谢谢。


1
2
3
4
5
6
function sortAlphaNum(a, b) {
    var smlla = a.toLowerCase();
    var smllb = b.toLowerCase();
    var result = smlla > smllb ? 1 : -1;
    return result;
}