2010-07-01 20 views
2

j'ai le problème suivant J'ai une liste avec des chaînes par exemple (100_1, 100_2 ...., 100_10)C# liste Trier, logique Comparer

trier la liste avec le code suivant

extraImgsRaw.Sort((photo1, photo2) => photo1.CompareTo(photo2)); 

le résultat de ceci est: 100_1, 100_10, 100_2, 100_3 et ainsi de suite

le résultat que je veux est logique comparer comme 100_1, 100_2 puis 100_10 donc je préfère une sorte numérique naturel pas une sorte alphabétique . Ai-je besoin d'écrire ma propre classe de comparaison qui implémente l'interface ICompare ou une méthode de construction dans LINQ qui le fait?

vous remercie à l'avance

+2

il y a rien de construit. Vous pouvez pirater votre propre chose, ou jetez un oeil à ceci: http://stackoverflow.com/questions/248603/natural-sort-order-in-c –

Répondre

4

Il n'y a rien intégré, mais si les données sont exactement comme indiqué dans votre question, alors il ne devrait pas être trop difficile à frapper un Comparison<T> à faire pour vous:

extraImgsRaw.Sort((x, y) => 
        { 
         // error checking etc removed for brevity 
         int[] xi = x.Split('_').Select(int.Parse).ToArray(); 
         int[] yi = y.Split('_').Select(int.Parse).ToArray(); 

         int c = xi[0].CompareTo(yi[0]); 
         return (c != 0) ? c : xi[1].CompareTo(yi[1]); 
        }); 
+0

+1 J'écrivais la même réponse :) – digEmAll

+0

Une classe ou un type serait mieux dans ce cas IMO. Vous êtes susceptible de le réutiliser. – leppie

+0

@leppie: Si cela doit être réutilisé, je suis d'accord pour dire qu'un IComparer avec plus de gestion des erreurs, etc. est la solution. Si c'est juste un travail ponctuel rapide où l'utilisateur connaît le format exact des données, alors le 'Comparaison ' suffira généralement. – LukeH

1

Split et comparer des éléments,

Voici un j'ai écrit pour 'versions'.

/// <summary> 
    /// Only works for version numbers in the form a (. b (. c (. d)?)?)? 
    /// </summary> 
    public class VersionComponents : IComparable<VersionComponents> 
    { 
    readonly int[] components; 

    int[] GetComponents(string cpnumber) 
    { 
     var tokens = cpnumber.Split(".".ToCharArray(), 
            StringSplitOptions.RemoveEmptyEntries); 
     return tokens.Select(x => Convert.ToInt32(x)).ToArray(); 
    } 

    public VersionComponents(string cpnumber) 
    { 
     components = GetComponents(cpnumber); 
    } 

    public int this[int index] 
    { 
     get { return components.Length > index ? components[index] : 0; } 
    } 

    public int CompareTo(VersionComponents other) 
    { 
     for (int i = 0; i < components.Length || 
         i < other.components.Length; i++) 
     { 
     var diff = this[i].CompareTo(other[i]); 
     if (diff != 0) 
     { 
      return diff; 
     } 
     } 

     return 0; 
    } 
    }