Question

Je cherche un conteneur qui garde tous ses articles en ordre. J'ai consulté SortedList, mais cela nécessite une clé séparée et n'autorise pas les clés en double. Je pourrais aussi simplement utiliser un conteneur non trié et le trier explicitement après chaque insertion.

Utilisation:

  • Insert occasionnel
  • parcours fréquent dans l'ordre
  • Idéalement, ne pas travailler avec des clés séparées de l'objet réel, en utilisant une fonction de comparaison pour trier.
  • Un tri stable pour des objets équivalents est souhaité, mais pas obligatoire.
  • Un accès aléatoire n'est pas requis.

Je réalise que je peux simplement me construire une arborescence équilibrée. Je me demandais si le cadre contenait déjà une telle bête.

Était-ce utile?

La solution

Vous pouvez consulter les collections Wintellect Power . Il est disponible sur CodePlex et contient quelques collections très utiles. La collection OrderedBag du projet correspond exactement à ce que vous recherchez. Il utilise essentiellement un arbre rouge-noir pour fournir un tri assez efficace.

Autres conseils

Juste pour faire le commentaire d'Ebarr En guise de réponse, il existe SortedSet<T> depuis .NET 4.0. Bien entendu, il s’agit d’un ensemble, ce qui signifie que vous ne pouvez pas avoir de doublons.

J'étendrais votre propre classe list qui, comme vous l'avez mentionné, trie simplement après chaque insertion. Étant donné que vos insertions sont peu fréquentes, l'impact sur les performances serait minime, et le tri d'une liste presque triée est rapide, dans tous les cas. Étendez la liste générique et remplacez la méthode Add pour trier immédiatement. Si les performances deviennent un problème, vous pouvez les insérer sur place pour gagner du temps. De plus, vous pouvez mettre vos insertions en file d'attente pour faire une insertion de traversée unique pour toutes les valeurs que vous souhaitez insérer.

Si vous souhaitez simplement vous en tenir aux collections standard, la fonction Sort(IComparer<>) de la classe List<> est souvent ignorée. Tout ce que vous avez à faire est de créer un Comparer<> approprié pour vos objets. Par exemple:

public class PositionDateComparer : IComparer<VehiclePosition>
{
    public int Compare(VehiclePosition x, VehiclePosition y)
    {
        if (x.DateTime == DateTime.MinValue)
        {
            if (y.DateTime == DateTime.MinValue)
            {
                // If x is null and y is null, they're
                // equal. 
                return 0;
            }

            // If x is null and y is not null, y
            // is greater. 
            return -1;
        }

        // If x is not null...
        //
        if (y.DateTime == DateTime.MinValue)
        // ...and y is null, x is greater.
        {
            return 1;
        }

        // ...and y is not null, compare the dates
        //
        if (x.DateTime == y.DateTime)
        {
            // x and y are equal
            return 0;
        }

        if (x.DateTime > y.DateTime)
        {
            // x is greater
            return 1;
        }

        // y is greater
        return -1;
    }
}

Ensuite, effectuez un vehiclePositionsList.Sort(new PositionDateComparer()) chaque fois que vous souhaitez trier la liste avant d'y accéder. Je réalise que ce n’est peut-être pas aussi simple qu’un conteneur qui trie automatiquement chaque fois que vous ajoutez un nouvel objet, mais pour beaucoup (comme moi!), Cela pourrait suffire à faire le travail avec succès sans avoir besoin de bibliothèques supplémentaires.

Comme je l'ai déjà mentionné aujourd'hui, Ici , la bibliothèque de collections génériques C5 contient le conteneur approprié.

Si la clé est également un attribut de l'objet, vous pouvez essayer le System.Collections.ObjectModel.KeyedCollection<TKey, TItem>. C'est une classe abstraite, mais si votre clé n'est qu'une propriété de l'élément, il est très simple d'en déduire.

Voici un vieux truc que j'avais utilisé dans VB6 pour trier les choses par ordre alphabétique: utilisez un objet System.Windows.Forms ListBox et définissez son " Trié " propriété à true. En C #, vous pouvez insérer n’importe quel objet dans la zone de liste et il triera cet objet par ordre alphabétique en fonction de sa valeur ToString ():

pour un module de classe:

using System.Windows.Forms;

    static void Main(string[] args)
    {
        ListBox sortedList = new ListBox();
        sortedList.Sorted = true;

        sortedList.Items.Add("foo");
        sortedList.Items.Add("bar");
        sortedList.Items.Add(true);
        sortedList.Items.Add(432); 

        foreach (object o in sortedList.Items)
        {
            Console.WriteLine(o);
        }

        Console.ReadKey();
    }

Ceci affichera:

432
bar
foo
Vrai

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top