IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Framework .NET Discussion :

Tri et collections


Sujet :

Framework .NET

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    50
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2006
    Messages : 50
    Par défaut Tri et collections
    Bonjour,

    je débute en dot net et je me pose des questions sur le tri de collections.

    concrètement j'ai une Ilist qui contient des instances de ma classe Personne et je souhaiterai trier cette iList en fonction de propriétés des Personnes, donc je voudrais pouvoir les trier par exemple sur leur id (integer) leur age (integer) ou le nbr de personnes dans leur ménage (integer)

    j'ai fait pas mal de recherches avant de poser la question ici et apparament il faut implementer dans ma classe Personne l'interface Icomparable ou Icomparer.

    Ce que je ne comprends pas c'est pourquoi pour comparer/trier des integer je dois aller coder du code spécifique, si je voulais trier sur base d'une propriété complexe de type classe ou autre ok mais là je trouve dotnet un peu "bête" et surtout très laborieux parceque bien sûr je n'ai pas qu'une classe personne dans mon application et je n'ai pas non plus que 3 propriétés mais des dizaines voire des centaines et je me vois mal aller coder 100 fois presque le même test pour comparer la valeur de 2 integers...

    ou bien y a t'il moyen de coder un comparateur générique ?

    voilà je sais pas si je m'y prends mal (sûrement) ou bien si c'est la méthode "normale" mais j'espère bien que non parceque niveau productivité c'est vraiment pas terrible si il faut coder un truc cpécifique à chaque fois pour comparer 2 valeurs numériques...

  2. #2
    Membre à l'essai
    Inscrit en
    Janvier 2007
    Messages
    6
    Détails du profil
    Informations forums :
    Inscription : Janvier 2007
    Messages : 6
    Par défaut
    Salut,

    J'ai déjà expérimenté les interfaces IComparer et IComparable. On n'a pas de choix d'implanter notre méthode de comparaison sur la ou les propriétés de la classe des objets dans la collection à trier. Comme on savait que même si la propriété est un entier, mais il faut quand-même implanter la méthode de comparaison. De plus, si on veut trier sur plusieurs propriétés de différent types (integer, string, ...), la méthode de comparaison devient des fois très compliquée à implanter.

    Je suggère d'implanter une seule méthode de tri sur n'importe quelle classe d'objets. La méthode va accepter comme paramètres:
    1. La collection de départ
    2. Le type de la classe d'objets
    3. La liste (key, valeur) des noms et valeurs de chacune des propriétés sur lesquelles le tri sera fait

    Voici les étapes que la méthode devrait faire:
    1. Créer un DataSet (ou plus optimisé avec un DataTable) à partir des 2 paramètres "la collection de départ et le type de la classe d'objet"
    2. Remplir le DataSet (ou le DataTable) avec les objets provenant de la collection de départ
    3. Par réflexion, construire une clause WHERE à partir du paramètre de la liste (key, valeur) et appeler la méthode Select(clauseWHERE) du DataSet (ou DataTable)
    4. Construire la collection de résultat à partir du résultat de la méthode Select(clauseWHERE). La collection de résultat est le résultat voulu.

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    50
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2006
    Messages : 50
    Par défaut
    merci pour ta réponse

  4. #4
    Membre expérimenté Avatar de scifire
    Inscrit en
    Juillet 2004
    Messages
    226
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 226
    Par défaut
    Salut.
    Je te propose de regarder le code suivant
    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
            static void Main(string[] args)
            {
                Random r = new Random(0);
                Group<Personne> group = new Group<Personne>();
                for (int i = 0; i < 10; i++)
                {
                    group.Add(new Personne(r.Next(100), r.Next(100)));
                }
     
                // Sort by default
                group.Sort();
     
                // Sort by Field
                group.Sort(Field.Age);
     
            }
            public enum Field
            {
                ID,
                Age
            }
     
            /// <summary>
            /// Demo classe Personne
            /// </summary>
            public class Personne
            {
                private int id;
     
                public int ID
                {
                    get { return id; }
                    set { id = value; }
                }
     
                private int age;
     
                public int Age
                {
                    get { return age; }
                    set { age = value; }
                }
     
                public Personne(int id, int age)
                {
                    this.ID = id;
                    this.Age = age;
                }
            }
     
            /// <summary>
            /// Custom collection with support of multiple sort expression
            /// </summary>
            /// <typeparam name="TObject"></typeparam>
            public class Group<TObject> : List<TObject> where TObject : Personne
            {
                public Group()
                {
                    // Default expression is ID
                    this.SortExpression = Field.ID;
                }
                private Field sortExpression;
     
                public Field SortExpression
                {
                    get { return sortExpression; }
                    set { sortExpression = value; }
                }
     
                public void Sort(Field expression)
                {
                    this.SortExpression = expression;
                    this.Sort();
                }
     
                public new void Sort()
                {
                    Console.WriteLine("Sort by " + this.SortExpression);
                    this.Sort(new Comparison<TObject>(this.Compare));
                }
     
                public int Compare(TObject x, TObject y)
                {
                    return this.CompareImpl(x, y);
                }
     
                protected virtual int CompareImpl(TObject x, TObject y)
                {
                    switch (this.SortExpression)
                    {
                        case Field.ID:
                            return x.ID.CompareTo(y.ID);
                        case Field.Age:
                            return x.Age.CompareTo(y.Age);
                        default:
                            throw new Exception("Invalid Field");
                    }
                }
            }
    Si tu dois changer la logique de la comparaison la seule chose que tu dois changer c'est la methode
    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
                protected virtual int CompareImpl(TObject x, TObject y)
                {
                    switch (this.SortExpression)
                    {
                        case Field.ID:
                            return x.ID.CompareTo(y.ID);
                        case Field.Age:
                            return x.Age.CompareTo(y.Age);
                        default:
                            throw new Exception("Invalid Field");
                    }
                }
    Lire bien le code et tu vas vite compredre qu'il n'y a rien de special et qu'il est tres puissant.
    A+

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    50
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2006
    Messages : 50
    Par défaut
    merci scifire ça m'a l'air proche de ce que j'attendais, je vais tester ça (dès demain )

  6. #6
    Membre à l'essai
    Inscrit en
    Janvier 2007
    Messages
    6
    Détails du profil
    Informations forums :
    Inscription : Janvier 2007
    Messages : 6
    Par défaut
    Salut,

    Avec la solution List<Object>, tu devrais implanter la méthode de comparaison pour chaque classe Object de List<Object>. Et cela revient au même problème de départ que tou voulais éviter. Est-ce que j'ai raison? La solution avec DataSet (DataTable) te libère de cette inconvénience.

    Bonne chance!

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Problème de tri sur collection d'enfants hétérogènes
    Par touftouf57 dans le forum XSL/XSLT/XPATH
    Réponses: 1
    Dernier message: 04/02/2013, 01h21
  2. Tri sur Collections
    Par fetrix dans le forum Collection et Stream
    Réponses: 4
    Dernier message: 22/10/2009, 13h45
  3. algorithme de tri de collection d'objets
    Par TaymouWan dans le forum Algorithmes et structures de données
    Réponses: 3
    Dernier message: 17/07/2009, 12h37
  4. Débutant comment trié une collection ?
    Par gold15 dans le forum PL/SQL
    Réponses: 1
    Dernier message: 11/02/2009, 13h21
  5. Tri de collection d'objets
    Par ds-network dans le forum Général JavaScript
    Réponses: 5
    Dernier message: 14/08/2007, 21h03

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo