2009-04-29 9 views
3

Pour trier une liste de critères multiples, je suis en train de faire quelque chose comme:Tri fréquent d'une liste <T> sur plusieurs critères en utilisant des méthodes d'extension?

collection.Sort((f1, f2) => 
{ 
    var comp = f1.FirstCriteria.CompareTo(f2.FirstCriteria); 
    return comp != 0 ? comp : f1.SecondCriteria.CompareTo(f2. SecondCriteria); 
}); 

Mais serait-il pas agréable de pouvoir faire quelque chose comme:

collection.MultipleSort(f1.FirstCriteria, f2.FirstCriteria) 
      .Then(f1.SecondCriteria, f2.SecondCriteria) 

Toutes les idées pour une bonne implémentation d'une interface fluide pour le tri?

Répondre

15

Vous voulez dire quelque chose comme ce qui suit?

using System.Linq; 

collection.OrderBy(t => t.FirstCriteria).ThenBy(t => t.SecondCriteria); 
+0

Maintenant, pourquoi Google n'a-t-il pas apporté ça? :-) Je devrais lire plus de livres avant de poser des questions! –

+0

La seule question serait alors comment faire en descendant? –

+4

@Hainsey, qu'en est-il de OrderByDescending et ThenByDescending? – LukeH

2

Le problème ici est qu'il semble que vous voulez faire une en place sorte; Dans ce cas, vous devez savoir (avec une API fluide) lorsque vous avez terminé d'ajouter des conditions. Cela contraste avec l'approche LINQ, car elle utilise une exécution différée.

Pour sortes unique condition, vous pouvez utiliser quelque chose comme:

public static void Sort<TSource, TValue>(this List<TSource> source, 
     Func<TSource, TValue> selector) { 
    var comparer = Comparer<TValue>.Default; 
    source.Sort((x,y)=>comparer.Compare(selector(x),selector(y))); 
} 
public static void SortDescending<TSource, TValue>(this List<TSource> source, 
     Func<TSource, TValue> selector) { 
    var comparer = Comparer<TValue>.Default; 
    source.Sort((x,y)=>comparer.Compare(selector(y),selector(x))); 
} 

Il serait plus difficile avec plusieurs sortes; vous ne pouvez pas utiliser params car chaque TValue peut être différent. Vous auriez probablement besoin d'utiliser une étape de terminaison et une classe "builder" intermédiaire (en écrivant essentiellement un DSL), ou vous auriez besoin de construire le comparateur séparément en premier.

Questions connexes