5 votes

Trier une liste avec un objet personnalisé par une autre liste en utilisant IComparer

Ma question porte sur le IComparer Je n'ai jamais travaillé avec l'interface, alors j'espère que vous pourrez m'aider à tout régler correctement.

Je dois utiliser l'interface pour trier une liste d'objets propres en fonction de la séquence exacte d'un autre objet. List<int> . Je n'ai rien trouvé d'utile pour ce problème sur le net, tout ce que j'ai trouvé était des instructions linq, que je ne peux pas utiliser.

Voici l'exemple de code :

public class What : IComparer<What>
{
    public int ID { get; set; }
    public string Ever { get; set; }

    public What(int x_ID, string x_Ever)
    {
        ID = x_ID;
        Ever = x_Ever;
    }

    public int Compare(What x, What y)
    {
        return x.ID.CompareTo(y.ID);
    }
}

Quelques données pour travailler :

List<What> WhatList = new List<What>()
{
    new What(4, "there"),
    new What(7, "are"), 
    new What(2, "doing"),
    new What(12, "you"),
    new What(78, "Hey"),
    new What(63, "?")
};

Et la liste avec l'ordre correct :

List<int> OrderByList = new List<int>() { 78, 4, 63, 7, 12, 2 };

Alors maintenant, comment puis-je dire IComparer pour trier par le OrderByList ? Je ne sais vraiment pas comment faire, je sais que ce serait assez facile avec linq, mais je n'ai pas l'occasion de l'utiliser.

5voto

Jamiec Points 35773

Il y a plusieurs choses qui ne vont pas avec votre code tel qu'il est actuellement. Si vous regardez le documents pour IComparer<T> vous verrez que le T est ce que vous dites que vous allez comparer. Dans votre code, c'est Test mais vous continuez à coder pour des comparaisons de What - cela signifie que votre code ne sera pas compilé. Voir aquí - Le message d'erreur est le suivant :

Rextester.What' ne met pas en œuvre le membre d'interface 'System.Collections.Generic.IComparer.Compare(Rextester.Test, Rextester.Test)'.
(Ignorez le mot "Rextester" !).

Tout cela étant dit et fait, vous devriez mettre en place une WhatComparer :

public class WhatComparer : IComparer<What>
{
    private List<int> orderBy;
    public WhatComparer(List<int> orderBy)
    {
        this.orderBy = orderBy;
    }

    public int Compare(What x, What y)
    {
        return orderBy.IndexOf(x.ID).CompareTo(orderBy.IndexOf(y.ID));
    }
}

Et utiliser ça pour commander :

 WhatList.Sort(new WhatComparer(OrderByList));

Exemple concret : http://rextester.com/BZKO33641

3voto

Lee Points 63849

Vous devriez créer une autre classe pour effectuer la comparaison, et lui donner l'ordre souhaité :

public class OrderComparer : IComparer<What>
{
    private readonly Dictionary<int, int> idIndexes = new Dictionary<int, int>();
    public OrderComparer(List<int> idOrders)
    {
        for(int i = 0; i < idOrders.Length; i++)
        {
            idIndexes[idOrders[i].ID] = i;
        }
    }

    public int Compare(What x, What y)
    {
        return idOrders[x.ID].Compare(idOrders[y.ID]);
    }
}

Alors vous pouvez le faire :

WhatList.Sort(new OrderComparer(OrderByList));

2voto

Paolo Moretti Points 9519

Le moyen le plus simple est d'utiliser un modèle personnalisé de Comparison<T> :

WhatList.Sort((x, y) =>
{
    return OrderByList.IndexOf(x.ID).CompareTo(orderByList.IndexOf(y.ID));
});

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