2011-01-24 8 views
14

Ho una lista come questa:Ordinamento una lista di stringhe numericamente (1,2, ..., 9,10 invece di 1,10,2)

var l = new List<string> {"bla 1.txt","bla 2.txt","bla 10.txt","bla 3.txt"}; 

se chiamo l.Sort (), la lista viene ordinata nell'ordine 1,10,2,3 che ha senso dal punto di vista della pura stringa, ma fa schifo da una prospettiva utente.

Dal momento che non voglio/non posso forzare i miei utenti a nominarli 01, 02, 03, ... Mi chiedo se c'è un metodo integrato o un semplice algoritmo per rilevare e ordinare i numeri correttamente , quindi ho 1,2,3,10? Dato che i numeri sono lunghi solo 1 o 2 caratteri (cioè non più di 99), potrei fare una regex che prefissa temporaneamente tutti i numeri a 1 cifra con 0 e sort, ma prima di reinventare la ruota mi chiedo se qualcosa esiste già ?

.net 3.5SP1 se quello che conta, non 4,0

+1

Aspetti correlati, dare un'occhiata a http://stackoverflow.com/questions/1022203/sorting-strings-contain-numbers-in-a-user-friendly-way – VoodooChild

+0

Duplicato di http://stackoverflow.com/ q/248603/24874 –

risposta

20

L'approccio migliore sta facendo uso di IComparer. Questo è già stato fatto e può essere found on code project.

+1

+1 ... o utilizzare una soluzione esistente –

+0

Ho usato questa stessa soluzione in passato - ha funzionato come un fascino! – Pwninstein

+1

Mi piacciono le soluzioni esistenti e testate: funziona come un fascino! Suggerimento per chiunque voglia utilizzare questo: Sbarazzarsi di NumericComparer.cs, spostare la funzione Compare in StringLogicalComparer, rendere il confronto (stringa, stringa) non-statico e avere la classe implementare IComparer, IComparer

0

È possibile implementare il proprio IComparer che forse utilizza un'espressione regolare sull'input ("bla 1.txt"), lo converte in un int e peforma il confronto su quel valore analizzato.

10

Perché non scrivere qualcosa che estrarrà un numero da una stringa, come questo?

// Note: This could very well be a bad implementation. I'm not too great with Regex. 
static int ExtractNumber(string text) 
{ 
    Match match = Regex.Match(text, @"(\d+)"); 
    if (match == null) 
    { 
     return 0; 
    } 

    int value; 
    if (!int.TryParse(match.Value, out value)) 
    { 
     return 0; 
    } 

    return value; 
} 

Allora si potrebbe ordinare l'elenco utilizzando:

list.Sort((x, y) => ExtractNumber(x).CompareTo(ExtractNumber(y))); 

Questo mi sembra abbastanza inefficiente, ma dovrebbe essere funzionale almeno.

Problemi correlati