Trier le tableau alphanumérique mixte

J'ai un tableau mixte que j'ai besoin de trier par l'alphabet puis par chiffre

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

Comment puis-je trier:

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

j'ai essayé

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

Mais cela ne l'aborde que par ordre alphabétique. Est-ce possible d'utiliser JavaScript ou jQuery directement?

Je vous remercie!

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

J'ai eu une situation similaire, mais j'ai eu un mélange d'alphanumériques et numériques et j'ai besoin de trier tous les numériques d'abord suivis d'alphanumériques, alors:

 A10 1 5 A9 2 B3 A2 

Devait devenir:

 1 2 5 A2 A9 A10 B3 

J'ai pu utiliser l'algorithme fourni et pirater un peu plus pour y parvenir:

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

Cela pourrait le faire:

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

J'ai résolu le problème de tri ci-dessus avec le script ci-dessous

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

Cela fonctionne bien pour un tableau bien mixé. 🙂

Je vous remercie.

En ajoutant à la réponse acceptée d'epascarello, puisque je ne peux pas commenter. Je suis toujours un noob ici. Quand l'un des strings n'a pas de numéro, la réponse originale ne fonctionnera pas. Par exemple, A et A10 ne seront pas triés dans cet ordre. Par conséquent, vous pourriez ne pas revenir au classement normal dans ce cas.

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

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

Usage:

['A1', 'A10', 'A11', 'A12', 'A2', 'A3', 'A4', 'B10', 'B2', 'F1', 'F12', 'F3'].sort(sortAlphaNum)

Donne:

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

Vous devrez peut-être modifier l'argument 'en' dans vos paramètres régionaux ou déterminer par programme, mais cela fonctionne pour les chaînes anglaises.

Également localeCompare n'est pas très compatible, mais si votre transpilage avec babel ne sera pas un problème

Le seul problème avec la solution donnée ci-dessus était que la logique a échoué lorsque les données numériques étaient identiques et les alphabets variaient, par exemple 28AB, 28PQR, 28HBC. Voici le code modifié.

 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; } 
 function sortAlphaNum(a, b) { var smlla = a.toLowerCase(); var smllb = b.toLowerCase(); var result = smlla > smllb ? 1 : -1; return result; }