2011-01-24 16 views
14

Tengo una lista como esta:Ordenar una lista de cadenas numéricamente (1,2, ..., en lugar de 9,10 1,10,2)

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

si llamo l.Sort (), la lista se clasifica en el orden 1,10,2,3 que tiene sentido desde un punto de vista de cadena de caracteres puro, pero es una mierda desde una perspectiva de usuario.

Como no quiero/no puedo obligar a mis usuarios a nombrarlos 01, 02, 03, ... Me pregunto si hay un método incorporado o un algoritmo simple para detectar y ordenar los números correctamente , entonces tengo 1,2,3,10? Dado que los números tienen solo 1 o 2 caracteres (es decir, no más de 99) podría hacer una expresión regular que prefija temporalmente todos los números de 1 dígito con un 0 y ordenar, pero antes de reinventar la rueda me pregunto si algo ya existe. ?

3.5SP1 .net si lo que importa, no

4.0
+1

Parece relacionado, eche un vistazo a http://stackoverflow.com/questions/1022203/sorting-strings-containing-numbers-in-a-user-friendly-way – VoodooChild

+0

Duplicate of http://stackoverflow.com/ q/248603/24874 –

Respuesta

20

El mejor enfoque es hacer uso de IComparer. Esto ya se ha hecho y puede ser found on code project.

+1

+1 ... o use una solución existente –

+0

He utilizado esta misma solución en el pasado - ¡funcionó como un amuleto! – Pwninstein

+1

Me gustan las soluciones existentes y probadas: ¡funciona como un encanto! Sugerencia para cualquiera que quiera usar esto: Deshágase de NumericComparer.cs, mueva la función Compare a StringLogicalComparer, haga que Compare (cadena, cadena) no estética y haga que la clase implemente IComparer, IComparer

0

Puede implementar su propio IComparer que tal vez use una expresión regular en la entrada ("bla 1.txt"), lo convierta en un int y ajuste la comparación en ese valor analizado.

10

¿Por qué no escribir algo que extraiga un número de una cadena, como este?

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

Posteriormente, se podría ordenar la lista usando:

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

Esto me parece bastante ineficiente, pero debe ser funcional por lo menos.