91 votes

Le tri d'un IList en C#

Donc, je suis tombé sur un problème intéressant aujourd'hui. Nous avons un service web WCF qui renvoie un IList. Pas vraiment une grosse affaire jusqu'à ce que je voulais faire le tri.

S'avère l'interface IList ne dispose pas d'une méthode de tri intégrées.

J'ai fini à l'aide de l' ArrayList.Adapter(list).Sort(new MyComparer()) méthode pour résoudre le problème, mais il me semblait un peu "ghetto" pour moi.

J'ai joué avec l'écriture d'une méthode d'extension, également avec l'héritage de IList et la mise en œuvre de ma propre méthode sort() ainsi que le moulage d'une Liste, mais aucun de ces semblait trop élégant.

Donc ma question est, quelqu'un aurait-il une solution élégante pour le tri d'un IList

72voto

Mark Cidade Points 53945

Vous pouvez utiliser LINQ:

using System.Linq;

IList<Foo> list = new List<Foo>();
IEnumerable<Foo> sortedEnum = list.OrderBy(f=>f.Bar);
IList<Foo> sortedList = sortedEnum.ToList();

63voto

David Mills Points 1168

Cette question m'a inspiré à écrire un post de blog: http://blog.velir.com/index.php/2011/02/17/ilistt-sorting-a-better-way/

Je pense que, idéalement, l' .NET Cadre comprendrait une statique de la méthode de tri qui accepte un IList<T>, mais la meilleure chose à faire est de créer votre propre méthode d'extension. Il n'est pas trop dur pour créer un couple de méthodes qui vous permettent de trier une IList<T> comme vous le feriez pour une Liste<T>. En bonus, vous pouvez surcharger le LINQ OrderBy méthode d'extension en utilisant la même technique, de sorte que si vous êtes en utilisant la Liste.Trier, IList.De tri ou de IEnumerable.OrderBy, vous pouvez utiliser la même syntaxe.

public static class SortExtensions
{
    //  Sorts an IList<T> in place.
    public static void Sort<T>(this IList<T> list, Comparison<T> comparison)
    {
        ArrayList.Adapter((IList)list).Sort(new ComparisonComparer<T>(comparison));
    }

    // Convenience method on IEnumerable<T> to allow passing of a
    // Comparison<T> delegate to the OrderBy method.
    public static IEnumerable<T> OrderBy<T>(this IEnumerable<T> list, Comparison<T> comparison)
    {
        return list.OrderBy(t => t, new ComparisonComparer<T>(comparison));
    }
}

// Wraps a generic Comparison<T> delegate in an IComparer to make it easy
// to use a lambda expression for methods that take an IComparer or IComparer<T>
public class ComparisonComparer<T> : IComparer<T>, IComparer
{
    private readonly Comparison<T> _comparison;

    public ComparisonComparer(Comparison<T> comparison)
    {
        _comparison = comparison;
    }

    public int Compare(T x, T y)
    {
        return _comparison(x, y);
    }

    public int Compare(object o1, object o2)
    {
        return _comparison((T)o1, (T)o2);
    }
}

Grâce à ces extensions, trier vos IList comme vous le feriez avec une Liste:

IList<string> iList = new []
{
    "Carlton", "Alison", "Bob", "Eric", "David"
};

// Use the custom extensions:

// Sort in-place, by string length
iList.Sort((s1, s2) => s1.Length.CompareTo(s2.Length));

// Or use OrderBy()
IEnumerable<string> ordered = iList.OrderBy((s1, s2) => s1.Length.CompareTo(s2.Length));

Il n'y a plus d'infos dans le post: http://blog.velir.com/index.php/2011/02/17/ilistt-sorting-a-better-way/

56voto

Brad Leach Points 9012

Comment sur l'utilisation de LINQ to Objects de trier pour vous?

Disons que vous avez un IList<Car>, et la voiture avait une Engine de la propriété, je crois que vous pourriez trier comme suit:

from c in list
orderby c.Engine
select c;

Edit: Vous avez besoin d'être rapide pour obtenir des réponses ici. Comme je l'ai présenté une syntaxe légèrement différente pour les autres réponses, je vais laisser ma réponse - toutefois, les autres réponses sont tout aussi valables.

9voto

Leon Bambrick Points 10886

Vous allez avoir à faire quelque chose comme ça, je pense que (le convertir en un plus type de béton).

Peut-être est-il tenir une Liste de T plutôt que de liste de tableaux, de sorte que vous obtenez le type de sécurité et plus d'options pour vous de mettre en œuvre les comparer.

-1voto

lubos hasko Points 13669

Convertir votre IList en List<T> ou certains autres de collection générique et puis vous pouvez facilement requête/tri à l'aide du Système.Linq espace de noms (il fournira des tas de méthodes d'extension)

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