Ordina array alfa / numerico misti

Ho una matrice mista che ho bisogno di ordinare per alfabeto e poi per cifra

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

come lo ordino per essere:

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

Ho provato

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

ma questo lo ordina solo in ordine alfabetico. Questo può essere fatto con JavaScript dritto o jQuery?

Grazie!

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

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)

dà:

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

Potrebbe essere necessario cambiare l’argomento 'en' nella propria locale o determinarlo a livello di codice, ma questo funziona con le stringhe in inglese.

Anche localeCompare non è super supportato in modo consistente, ma se il tuo transpiling con babel non sarà un problema

Avevo una situazione simile, ma avevo un mix di alfanumerico e numerico e dovevo ordinare tutti i numeri numerici prima seguiti da alfanumerici, quindi:

 A10 1 5 A9 2 B3 A2 

necessario per diventare:

 1 2 5 A2 A9 A10 B3 

Sono stato in grado di utilizzare l’algoritmo fornito e ci ho aggiunto un po ‘di più per ottenere questo risultato:

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

Questo potrebbe farlo:

 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'])) 

L’unico problema con la soluzione sopra riportata era che la logica non funzionava quando i dati numerici erano uguali e gli alfabeti variavano ad esempio 28AB, 28PQR, 28HBC. Ecco il codice modificato.

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

Aggiungendo alla risposta accettata da epascarello, dal momento che non posso commentare su di esso. Sono ancora un noob qui. Quando uno degli strinngs non ha un numero, la risposta originale non funzionerà. Ad esempio A e A10 non verranno ordinati in questo ordine. Quindi potresti non tornare al normale tipo in quel 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);` 

Ho risolto il suddetto problema di ordinamento con lo script seguente

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

Funziona bene per un array ben misto. 🙂

Grazie.

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

Ecco un aggiornamento ES6 Typescript a questa risposta.

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

}

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