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

C# Discussion :

[2.0] Comparer 2 List<T>


Sujet :

C#

  1. #1
    Membre chevronné
    Profil pro
    Développeur freelance
    Inscrit en
    Août 2006
    Messages
    453
    Détails du profil
    Informations personnelles :
    Localisation : France, Ardèche (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur freelance

    Informations forums :
    Inscription : Août 2006
    Messages : 453
    Par défaut [2.0] Comparer 2 List<T>
    Bonjour,

    je souhaiterais comparer 2 List contenant le même type d'objet afin d'effectuer un traitement sur la seconde liste.
    Je sais le faire en imbriquant 2 foreach comme ceci
    Code : 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
    List<MonObjet> List1 = ChargerList();
    List<MonObjet> List2 = new List<MonObjet>();
     
    foreach (MonObjet o1 in List1)
    {
        foreach (MonObjet o2 in List2)
        {
            if (o1.type == o2.type)
            {
                // Traitement adéquate
            }
            else
            {
               List2.Add(o1);
            }
    }
    Mais je souhaiterais trouver une autre solution sans faire des boucles inutiles et ne pas avoir une opération particulièrement lente.

    J'ai regardé au niveau des méthodes de List<T> mais je ne penses pas que cela réponde à mon besoin ou alors je n'ai pas compris

    Avez-vous des conseils ?

    Merci par avance.
    Mosco

  2. #2
    Membre confirmé
    Inscrit en
    Août 2007
    Messages
    174
    Détails du profil
    Informations forums :
    Inscription : Août 2007
    Messages : 174
    Par défaut
    En 2.0, je crains que tu devras te contenter de ces boucles.
    En 3.5, avec Linq tu peux requeter plus facilement sur 2 List.

    Par contre, dans ton exemple ta 2eme liste est vide (et donc o1.type ne sera jamais égale à o2.type).

  3. #3
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    Je suppose que dans ton vrai code tu fais quelque chose entre la création de List2 et le début de la boucle ? Parce que sinon ça sert à rien de chercher des éléments de List1 dans List2, vu que List2 est vide...

    Le problème de ton code actuel, c'est que pour chaque élément de la première liste, tu parcours entièrement la deuxième... Pour éviter ça, il faudrait que tu les tries dans le même ordre, et que tu avances dans les 2 listes en même temps, avec une boucle for par exemple.

  4. #4
    Membre chevronné
    Profil pro
    Développeur freelance
    Inscrit en
    Août 2006
    Messages
    453
    Détails du profil
    Informations personnelles :
    Localisation : France, Ardèche (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur freelance

    Informations forums :
    Inscription : Août 2006
    Messages : 453
    Par défaut
    Bonjour et merci pour les réponses.

    Après réflexion, je me rends compte que mon besoin était mal exprimé (en plus de mon code qui ne donne rien ).
    En fait, je récupère une List<T> d'objets, ces objets contiennent plusieurs propriétés (p1,p2,p3). Si dans cette List<T> plusieurs objets avaient la même valeur pour la propriété p2 alors je ne souhaitais en garder qu'un (d'où mon intérêt de construire une seconde List<T>).

    J'ai trouvé un moyen de coder ça sans construire une 2nd List<T>.
    Code : 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
    List<MonObjet> liste = null;
    liste = ChargerListMonObjet();
     
    liste.ForEach(delegate (MonObjet obj1)
    {
        List<MonObjet> tmp = liste.FindAll(delegate (MonObjet obj2)
        {
           if (obj1.p2 == obj2.p2)
             return true;
           else
             return false;
        });
     
        if (tmp.Count > 1)
        {
           MonObjet newobj = tmp[0];
           tmp.ForEach(delegate(MonObjet obj2)
           {
              liste.Remove(obj2);
     
              // Taritement sur newobj
     
           });
           liste.Add(newobj);
        }
    });
    Que pensez-vous de ce code ? N'y a-t-il pas un moyen plus simple de le coder ? d'optimiser ?

    Mosco.

  5. #5
    Membre expérimenté
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    203
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 203
    Par défaut
    Pourquoi tu n'utilises pas directement la fonction linq Distinct(IEqualityComparer) ??

  6. #6
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    Perso j'aime pas trop la méthode ForEach : ça revient au même que faire une boucle foreach, c'est juste moins lisible...

    J'aurais fait un peu différemment : d'abord trier la liste selon p2, puis la parcourir en ne gardant que le premier pour chaque valeur de p2 :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
        Comparison<MonObjet> comparison = delegate(MonObjet a, MonObjet b) { return a.P2.CompareTo(b.P2); };
        liste.Sort(comparison);
        List<MonObjet> list2 = new List<MonObjet>();
        int tmp = -1;
        foreach(MonObjet x in liste)
        {
            if (x.p2 != tmp)
            {
                list2.Add(x);
                tmp = x.p2;
            }
        }

  7. #7
    Membre chevronné
    Profil pro
    Développeur freelance
    Inscrit en
    Août 2006
    Messages
    453
    Détails du profil
    Informations personnelles :
    Localisation : France, Ardèche (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur freelance

    Informations forums :
    Inscription : Août 2006
    Messages : 453
    Par défaut
    Citation Envoyé par matdur Voir le message
    Pourquoi tu n'utilises pas directement la fonction linq Distinct(IEqualityComparer) ??
    Parce que je suis en 2.0

  8. #8
    Membre chevronné
    Profil pro
    Développeur freelance
    Inscrit en
    Août 2006
    Messages
    453
    Détails du profil
    Informations personnelles :
    Localisation : France, Ardèche (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur freelance

    Informations forums :
    Inscription : Août 2006
    Messages : 453
    Par défaut
    Citation Envoyé par tomlev Voir le message
    Perso j'aime pas trop la méthode ForEach : ça revient au même que faire une boucle foreach, c'est juste moins lisible...
    En fait, j'ai lu partout sur le web que le foreach est bcp plus lent que List<T>.Foreach (qui est un plus lent que le for je peux avoir des milliers d'objets dans ma liste) et aussi car je ne l'avais jamais utilisé et je voulais voir ce que cela donnait.

    Citation Envoyé par tomlev Voir le message
    J'aurais fait un peu différemment : d'abord trier la liste selon p2, puis la parcourir en ne gardant que le premier pour chaque valeur de p2 :
    J'aime bien le Comparaison (ce n'est pas une classe que j'utilise souvent).
    En fait dans mon code je dois faire un traitement sur les objets avec p2 identiques (garder la date la plus élevée, changer la propriété p4 (string)).

    Quelles sont les différences au niveau des 2 codes en terme de vitesse, ou d'autres points.Sachant que point de vue lisibilité, ton code est meilleur à mon sens.

    En tout cas merci pour ta proposition, cela m'a permis d'avoir un autre point de vue.

    Mosco

  9. #9
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    Citation Envoyé par MoscoBlade Voir le message
    En fait, j'ai lu partout sur le web que le foreach est bcp plus lent que List<T>.Foreach (qui est un plus lent que le for je peux avoir des milliers d'objets dans ma liste)
    C'est pas beaucoup plus lent normalement... le foreach a un petit overhead à cause de l'énumérateur, mais en général c'est négligeable par rapport au corps de la boucle

    Citation Envoyé par MoscoBlade Voir le message
    Quelles sont les différences au niveau des 2 codes en terme de vitesse, ou d'autres points.Sachant que point de vue lisibilité, ton code est meilleur à mon sens.
    Ben avec ton code, tu as une complexité de O(n²) au minimum (pour chaque élément de la liste, tu reparcours toute la liste)

    Avec le mien, je fais un tri (a priori c'est implémenté avec l'algo Quicksort, donc une complexité de O(n log n)), puis un parcours de la boucle : O(n). Donc au final nettement mieux que O(n²)

  10. #10
    Membre chevronné
    Profil pro
    Développeur freelance
    Inscrit en
    Août 2006
    Messages
    453
    Détails du profil
    Informations personnelles :
    Localisation : France, Ardèche (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur freelance

    Informations forums :
    Inscription : Août 2006
    Messages : 453
    Par défaut
    Citation Envoyé par tomlev Voir le message
    Avec le mien, je fais un tri (a priori c'est implémenté avec l'algo Quicksort, donc une complexité de O(n log n)), puis un parcours de la boucle : O(n). Donc au final nettement mieux que O(n²)
    Merci pour l'info

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

Discussions similaires

  1. Comparer deux listes
    Par timtim2007 dans le forum Prolog
    Réponses: 7
    Dernier message: 07/06/2019, 09h02
  2. comparer une liste de valeur
    Par jfcb92 dans le forum Excel
    Réponses: 4
    Dernier message: 14/11/2007, 08h36
  3. Comparer x listes de x serveurs
    Par MaitrePylos dans le forum Langage
    Réponses: 1
    Dernier message: 12/10/2007, 09h58
  4. [C# 2.0] Comparer deux listes
    Par Rodie dans le forum Windows Forms
    Réponses: 4
    Dernier message: 01/08/2006, 00h40
  5. Comparer des listes de prix
    Par denisfavre dans le forum Access
    Réponses: 8
    Dernier message: 08/11/2005, 20h11

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