我有一个混合数组,我需要按字母顺序排序,然后按数字
排序[A1, A10, A11, A12, A2, A3, A4, B10, B2, F1, F12, F3]
如何将其排序为:
[A1, A2, A3, A4, A10, A11, A12, B2, B10, F1, F3, F12]
我试过了
arr.sort(function(a,b) {return a - b});
但只按字母顺序对其进行排序。 可以使用直接JavaScript或jQuery来完成吗?
答案 0 :(得分:78)
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 :(得分:20)
const sortAlphaNum = (a, b) => a.localeCompare(b, 'en', { numeric: true })`
用法:
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的转换不是一个问题
答案 2 :(得分:7)
我有类似的情况,但是,混合了字母数字和&数字,需要先排序所有数字后跟字母数字,所以:
A10
1
5
A9
2
B3
A2
需要成为:
1
2
5
A2
A9
A10
B3
我能够使用提供的算法并在其上进行更多操作来实现此目的:
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);
答案 3 :(得分:3)
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())
答案 4 :(得分:3)
这可以做到:
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']))
答案 5 :(得分:2)
上述解决方案的唯一问题是当数字数据相同时逻辑失败。字母表有所不同,例如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;
}
答案 6 :(得分:2)
一种简单的方法是使用JavaScript
https://www.w3schools.com/jsref/jsref_localecompare.asp
示例:
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);
};
预期行为:
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
答案 7 :(得分:1)
添加epascarello接受的答案,因为我无法发表评论。我在这里仍然是个菜鸟。 当其中一个strinngs没有数字时,原始答案将不起作用。例如,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);`
答案 8 :(得分:1)
我最近从事一个涉及库存和垃圾箱位置的项目。数据需要按bin位置排序,并且位于对象数组中。
对于任何想要处理此类数据排序并且您的数据位于对象数组中的人,您可以执行以下操作:
const myArray = [
{ location: 'B3', item: 'A', quantity: 25 },
{ location: 'A11', item: 'B', quantity: 5 },
{ location: 'A6', item: 'C', quantity: 245 },
{ location: 'A9', item: 'D', quantity: 15 },
{ location: 'B1', item: 'E', quantity: 65 },
{ location: 'SHOP', item: 'F', quantity: 42 },
{ location: 'A7', item: 'G', quantity: 57 },
{ location: 'A3', item: 'H', quantity: 324 },
{ location: 'B5', item: 'I', quantity: 4 },
{ location: 'A5', item: 'J', quantity: 58 },
{ location: 'B2', item: 'K', quantity: 45 },
{ location: 'A10', item: 'L', quantity: 29 },
{ location: 'A4', item: 'M', quantity: 11 },
{ location: 'B4', item: 'N', quantity: 47 },
{ location: 'A1', item: 'O', quantity: 55 },
{ location: 'A8', item: 'P', quantity: 842 },
{ location: 'A2', item: 'Q', quantity: 67 }
];
const sortArray = (sourceArray) => {
const sortByLocation = (a, b) => a.location.localeCompare(b.location, 'en', { numeric: true });
//Notice that I specify location here ^^ and here ^^ using dot notation
return sourceArray.sort(sortByLocation);
};
console.log('unsorted:', myArray);
console.log('sorted by location:', sortArray(myArray));
您也可以轻松地按其他任何键进行排序。在这种情况下,item
或quantity
使用点表示法,如摘要所示。
答案 9 :(得分:0)
我用下面的脚本解决了上面的排序问题
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;
}
});
这适用于混合良好的数组。:)
谢谢。
答案 10 :(得分:0)
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;
}
答案 11 :(得分:0)
这是此答案的ES6打字稿升级。
MeetingItem
}
答案 12 :(得分:0)
您可以使用Intl.Collator
与localeCompare
Read here
Browser comparability(所有浏览器都支持)
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)
答案 13 :(得分:0)
这对我有用,而且紧凑一些。
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);
});
答案 14 :(得分:0)
这是TypeScript中的一个版本(基于@SunnyPenguin和@Code Maniac的答案)作为库函数。更新了变量名并添加了注释,以使内容更加清晰。
// Sorts strings with numbers by keeping the numbers in ascending order
export const sortAlphaNum: Function = (a: string, b: string, locale: string): number => {
const letters: RegExp = /[^a-zA-Z]/g;
const lettersOfA: string = a.replace(letters, '');
const lettersOfB: string = b.replace(letters, '');
if (lettersOfA === lettersOfB) {
const numbers: RegExp = /[^0-9]/g;
const numbersOfA: number = parseInt(a.replace(numbers, ''), 10);
const numbersOfB: number = parseInt(b.replace(numbers, ''), 10);
if (isNaN(numbersOfA) || isNaN(numbersOfB)) {
// One is not a number - comparing letters only
return new Intl.Collator(locale, { sensitivity: 'accent' }).compare(a, b);
}
// Both have numbers - compare the numerical parts
return numbersOfA === numbersOfB ? 0 : numbersOfA > numbersOfB ? 1 : -1;
} else {
// Letter parts are different - comparing letters only
return new Intl.Collator(locale, { sensitivity: 'accent' }).compare(lettersOfA, lettersOfB);
}
};
答案 15 :(得分:-3)
function sortAlphaNum(a, b) {
var smlla = a.toLowerCase();
var smllb = b.toLowerCase();
var result = smlla > smllb ? 1 : -1;
return result;
}