Säg att jag visar data för en användare i ett rutnät, rapport, rullgardinsruta etc. Data i fråga innehåller ett fält som heter Fakturanummer . Det här fältet innehåller endast numerik 2/3 av tiden, men den andra 1/3 av tiden är en blandning av alfanumerik.
På grund av detta skulle alla sorteringsalgoritmer sortera alfanumeriskt istället för numeriskt . Av denna anledning skulle 1000 komma långt före 99. Eftersom den första siffran sorteras på – inte hela värdet. Andra objekt som 000333 skulle inte behandlas som ”333” och skulle visas före 222.
Finns det någon standard här? Ska jag försöka konvertera alla värden till ett numeriskt värde och sortera dem annorlunda? Hur skulle de integreras igen? Eller är alfanumerisk sortering rätt väg att gå?
Kommentarer
- Om du har möjlighet att säga, använd substring för att trunka de tre första siffror som har alfabet och sorterar enbart baserat på de tre sista siffrorna, i ditt fall säger ABC333 och 000222 – du kan implementera detta. Visst, när den visas skulle den komma i ordningen 000222 och sedan ABC333. Men visuellt skulle det vara lite förvirrande att se nollor mot få siffror och alfabet mot andra. Vad föreslår alfabet?
- Varierande längder så ingen SubString. Jag tror att se " 10 " komma före " 9 " (faktiskt FAR före 9) skulle vara förvirrande för användare som inte använder ' t ofta alfanumeriska siffror. Å andra sidan kan en ren blandning av dessa verkligen ' sorteras på något trevligt sätt som jag kan se.
- Om det här är fakturor kan du sortera dem efter datum eller behöver det uttryckligen sorteras efter själva fakturanumret? Kanske kan du använda en annan kolumn från tabellen och sortera dem därefter. Förutsatt att dessa genereras i ökande ordning, skulle en kronologisk ordning med fakturor med den vanligaste som genereras högst upp vettigt, nej? Jag är inte säker på vad rullgardinsmenyn egentligen är för eller hur kan användaren dra nytta av sorten. Om du kunde upplysa oss mer om användningen av fältet skulle det vara mycket mer användbart!
- Det ' är upp till användaren. De kan visa dessa data via rapportering, via en redovisningsskärm som låter dem kontrollera saldon mot Net 30 (se alla fakturor från en leverantör) etc. Användaren väljer hur de vill att skärmen eller rapporten ska sorteras. Datum är ett alternativ. Men så är fakturanumret också. Dessa genereras inte av min ansökan. Du beställer förnödenheter, delar etc från leverantörer. Den specifika leverantören sparkar tillbaka ett fakturanummer till dig. Som om du beställde från fem webbutiker och fick fem ordernummer. Vissa är numeriska, andra inte.
- Du bör konvertera dessa siffror till ett numeriskt format. Använd endast detta för att sortera de alfanumeriska värdena. De konverterade siffrorna behöver inte visas för användaren för att orsaka mer förvirring. Jag rekommenderar dock starkt att du har en annan kolumn till exempel – Datum för att komplettera alfanumerierna. Eftersom sortering av alfanumeriska tecken kommer att vara lite förvirrande skulle en annan kolumn som hjälper användaren att räkna ut det aktuella datumet eller något annat hjälpa mycket.
Svar
Från och med Windows 7 ändrade Microsoft sin standardmetod för att sortera kataloger efter filnamn för att använda ”numerisk” sortering. (Lite info här )
Även om jag inte kunde hitta en specifikation av dess beteende lyckades jag omvandla den. Denna algoritm borde jämföra två alfanumeriska strängar och bestäm vilken som kommer först.
-
Dela upp varje filnamn i alfabetiska och numeriska delar, dvs namnet
text123moretext456
blir det lista {"text"
,"123"
,"moretext"
,"456"
} -
För varje del i de två delade namnen, gör följande jämförelse:
- Om båda delarna är strikt numeriska, jämför dem som siffror
- Om siffrorna är desamma, jämför dem som strängar
- Om strängarna är desamma, gå vidare till nästa del
- Om båda delarna är strikt bokstäver, jämför dem som strängar
- Om de är desamma, gå vidare till nästa del
- Om båda delarna är strikt numeriska, jämför dem som siffror
- Om du har slut på delar kommer namnet med minst delar f första
Du får en beställning enligt följande:
2 12 200000 1000000 a a12 b2 text2 text2a text2a2 text2a12 text2b text12 text12a
Kommentarer
- Det här är precis vad jag letade efter och den resulterande sorteringsordningen är vettig. Tack!
Svar
Den här frågan (och speciellt @Harrison Paines svar) hade hjälpt mig på mitt projekt och jag vill ge [javascript] implementeringen av hans svar för framtida referens.Här är sorteringen function
:
var win7sort = function(a, b) { var regex = /[^\d]+|\d+/g; // Split each filename into alphabetical and numeric parts var ar = a.match(regex); var br = b.match(regex); var localeCompare; // For each part in the two split names, perform the following comparison: for(var ia in ar) { for(var ib in br) { var ari = ar[ib]; if(ari == undefined) { ari = ""; } var bri = br[ib]; if(bri == undefined) { bri = ""; } // If both parts are strictly numeric, compare them as numbers if(!isNaN(ari) && !isNaN(bri)) { localeCompare = ari.localeCompare(bri, {}, { numeric: true }); } else { localeCompare = ari.localeCompare(bri, {}, { ignorePunctuation: true, sensitivity: "base" }); } if(localeCompare != 0) { // If you run out of parts, the name with the fewest parts comes first return localeCompare; } // If they"re the same, move on to the next part } } return localeCompare; };
Och här är hur man använder det:
var list = ["1", "a", "z", "new folder 2", "new folder 03", "new folder 03-a", "new folder 039", "new folder 5", "new folder 41", "2", "21", "3", "41", "100"]; var sortedList = list.sort(win7sort);