javascript - por - Ordenar matriz alfa/numérica mixta
order an array (10)
Agregando a la respuesta aceptada de epascarello, ya que no puedo comentar sobre ella. Todavía soy un novato aquí. Cuando una de las cuerdas no tiene un número, la respuesta original no funcionará. Por ejemplo, A y A10 no se ordenarán en ese orden. Por lo tanto, es posible que desee volver al tipo normal en ese caso.
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);`
Tengo una matriz mixta que debo ordenar por alfabeto y luego por dígito
[A1, A10, A11, A12, A2, A3, A4, B10, B2, F1, F12, F3]
cómo lo clasifico para ser:
[A1, A2, A3, A4, A10, A11, A12, B2, B10, F1, F3, F12]
Yo he tratado
arr.sort(function(a,b) {return a - b});
pero eso solo lo ordena alfabéticamente ¿Se puede hacer esto con JavaScript directo o jQuery?
¡Gracias!
El único problema con la solución dada anteriormente fue que la lógica falló cuando los datos numéricos eran iguales y los alfabetos variaban, por ejemplo, 28AB, 28PQR, 28HBC. Aquí está el código modificado.
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;
}
Esto podría hacerlo:
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'']))
He resuelto el problema de clasificación anterior con la secuencia de comandos siguiente
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;
}
});
Esto funciona bien para una matriz bien mezclada :)
Gracias.
Tenía una situación similar, pero tenía una combinación de alfanumérico y numérico y necesitaba ordenar todo primero numérico seguido de alfanumérico, entonces:
A10
1
5
A9
2
B3
A2
necesario para convertirse en:
1
2
5
A2
A9
A10
B3
Pude utilizar el algoritmo suministrado y hackear un poco más para lograr esto:
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);
const sortAlphaNum = (a, b) => a.localeCompare(b, ''en'', { numeric: true })
Uso:
[''A1'', ''A10'', ''A11'', ''A12'', ''A2'', ''A3'', ''A4'', ''B10'', ''B2'', ''F1'', ''F12'', ''F3''].sort(sortAlphaNum)
Da:
["A1", "A2", "A3", "A4", "A10", "A11", "A12", "B2", "B10", "F1", "F3", "F12"]
Puede que tenga que cambiar el argumento ''en''
a su configuración regional o determinar programáticamente, pero esto funciona para cadenas en inglés.
También localeCompare
no es compatible de manera consistente, pero si transporta con Babel eso no será un problema
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;
}
function sortAlphaNum(a, b) {
var smlla = a.toLowerCase();
var smllb = b.toLowerCase();
var result = smlla > smllb ? 1 : -1;
return result;
}
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())
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;
}
}
["A1", "A10", "A11", "A12", "A2", "A3", "A4", "B10", "B2", "F1", "F12", "F3"].sort(sortAlphaNum);