147 votes

Ordonner une liste (C#) par plusieurs champs ?

Je veux ordonner une liste d'objets en C# par plusieurs champs, et pas seulement par un seul. Par exemple, supposons que j'ai une classe appelée X avec deux attributs, A et B, et que j'ai les objets suivants, dans cet ordre :

object1 => A = "a", B = "h"
object2 => A = "a", B = "c"
objet3 => A = "b", B = "x"
object4 => A = "b", B = "b"

et je veux ordonner la liste par l'attribut A en premier, et quand ils sont égaux, par l'élément B, donc l'ordre serait :

"a" "c"
"a" "h"
"b" "b"
"b" "x"

Pour autant que je sache, la méthode OrderBy commande par un seul paramètre.

Question : Comment ordonner une liste C# par plus d'un champ ?

374voto

David Neale Points 8596

Utilisez ThenBy :

var orderedCustomers = Customer.OrderBy(c => c.LastName).ThenBy(c => c.FirstName)

Voir MSDN : http://msdn.microsoft.com/en-us/library/bb549422.aspx

2 votes

Cela ne les a pas commandés pour moi ? Qu'est-ce que j'ai manqué ? docs.OrderBy(o => o.AcctNum) .ThenBy(o => o.DocDate) ;

0 votes

Vous utilisez peut-être une ancienne version de .net. Vérifiez cette réponse : stackoverflow.com/questions/289010/ .

17 votes

Pour la postérité : OrderBy ne trie pas la collection d'origine, il renvoie un IOrderedEnumerable<T>, vous devez donc affecter les résultats de OrderBy à une variable. ex. customers = customers.OrderBy(c=>c.Surname).ThenBy(c.Forename).ToList() ;

46voto

CMinus Points 638

Oui, vous pouvez le faire en spécifiant la méthode de comparaison. L'avantage est que l'objet trié n'a pas besoin d'être IComparable.

   aListOfObjects.Sort((x, y) =>
   {
       int result = x.A.CompareTo(y.A);
       return result != 0 ? result : x.B.CompareTo(y.B);
   });

8voto

Jason Jong Points 2811

Faites de votre objet quelque chose comme

public class MyObject : IComparable
{
    public string a;
    public string b;

    virtual public int CompareTo(object obj)
    {
        if (obj is MyObject)
        {
            var compareObj = (MyObject)obj;
            if (this.a.CompareTo(compareObj.a) == 0)
            {
                // compare second value
                return this.b.CompareTo(compareObj.b);
            }
            return this.a.CompareTo(compareObj.b);
        }
        else
        {
            throw new ArgumentException("Object is not a MyObject ");
        }
    }
}

Notez également que les retours pour CompareTo :

http://msdn.microsoft.com/en-us/library/system.icomparable.compareto.aspx

Ensuite, si vous avez une liste de MyObject, appelez .Sort() ie

var objList = new List<MyObject>();
objList.Sort();

0 votes

Question : Comment puis-je ordonner une liste C# par plus d'un champ ? OUI !

0voto

Oliver Points 19006

Votre objet doit implémenter la fonction IComparable interface.

Avec elle, votre classe devient une nouvelle fonction appelée CompareTo(T other) . Dans cette fonction, vous pouvez effectuer n'importe quelle comparaison entre l'objet actuel et l'autre objet et renvoyer une valeur entière indiquant si le premier est supérieur, inférieur ou égal au second.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X