Javascript 排序混合字母/数字数组
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4340227/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Sort mixed alpha/numeric array
提问by solefald
I have a mixed array that I need to sort by alphabet and then by digit
我有一个混合数组,我需要先按字母排序,然后再按数字排序
[A1, A10, A11, A12, A2, A3, A4, B10, B2, F1, F12, F3]
How do I sort it to be:
我如何将其排序为:
[A1, A2, A3, A4, A10, A11, A12, B2, B10, F1, F3, F12]
I have tried
我试过了
arr.sort(function(a,b) {return a - b});
but that only sorts it alphabetically. Can this be done with either straight JavaScript or jQuery?
但这只是按字母顺序排序。这可以用直接的 JavaScript 或 jQuery 来完成吗?
回答by epascarello
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)
)
回答by Jon Wyatt
const sortAlphaNum = (a, b) => a.localeCompare(b, 'en', { numeric: true })`
Usage:
用法:
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))
Gives:
给出:
["A1", "A2", "A3", "A4", "A10", "A11", "A12", "B2", "B10", "F1", "F3", "F12"]
["A1", "A2", "A3", "A4", "A10", "A11", "A12", "B2", "B10", "F1", "F3", "F12"]
You may have to change the 'en'
argument to your locale or determine programatically but this works for english strings.
您可能需要将'en'
参数更改为您的语言环境或以编程方式确定,但这适用于英文字符串。
localeCompare
is supported by IE11, Chrome, Firefox, Edge and Safari 10.
localeCompare
IE11、Chrome、Firefox、Edge 和 Safari 10 支持。
回答by cmcculloh
I had a similar situation, but, had a mix of alphanumeric & numeric and needed to sort all numeric first followed by alphanumeric, so:
我有类似的情况,但是,混合了字母数字和数字,需要先对所有数字进行排序,然后是字母数字,所以:
A10
1
5
A9
2
B3
A2
needed to become:
需要成为:
1
2
5
A2
A9
A10
B3
I was able to use the supplied algorithm and hack a bit more onto it to accomplish this:
我能够使用提供的算法并对其进行更多修改以完成此操作:
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);
回答by Mitali Bhokare
A simple way to do this is use the localeCompare() method of JavaScript
https://www.w3schools.com/jsref/jsref_localecompare.asp
一个简单的方法是使用https://www.w3schools.com/jsref/jsref_localecompare.asp的 localeCompare() 方法JavaScript
Example:
例子:
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);
};
Expected behavior:
预期行为:
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
回答by Josiah Ruddell
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())
回答by Jan
This could do it:
这可以做到:
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']))
回答by Jarna Kantaria
Only problem with the above given solution was that the logic failed when numeric data was same & alphabets varied e.g. 28AB, 28PQR, 28HBC. Here is the modified code.
上面给出的解决方案的唯一问题是当数字数据相同且字母不同时逻辑失败,例如 28AB、28PQR、28HBC。这是修改后的代码。
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;
}
回答by Code Maniac
You can use Intl.Collator
您可以使用 Intl.Collator
It has performance benefits over localeCompare
Read here
与Read here 相比,它具有性能优势localeCompare
Browser comparability( All the browser supports it )
浏览器可比性(所有浏览器都支持)
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)
回答by SunnyPenguin
Adding to the accepted answer from epascarello, since I cannot comment on it. I'm still a noob here. When one of the strinngs doesn't have a number the original answer will not work. For example A and A10 will not be sorted in that order. Hence you might wamnt to jump back to normal sort in that case.
添加到 epascarello 已接受的答案中,因为我无法对此发表评论。我在这里还是个菜鸟。当其中一个字符串没有数字时,原始答案将不起作用。例如,A 和 A10 不会按该顺序排序。因此,在这种情况下,您可能不想跳回正常排序。
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);`
回答by JOfford
This has worked for me and it's a bit more compact.
这对我有用,而且更紧凑。
const reg = /[0-9]+/g;
array.sort((a, b) => {
let v0 = a.replace(reg, v => v.padStart(10, '0'));
let v1 = b.replace(reg, v => v.padStart(10, '0'));
return v0.localeCompare(v1);
});