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 :

Distinct Elements dans List<T>


Sujet :

C#

  1. #21
    Membre Expert Avatar de Guulh
    Homme Profil pro
    Inscrit en
    Septembre 2007
    Messages
    2 160
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2007
    Messages : 2 160
    Par défaut
    Citation Envoyé par SaumonAgile Voir le message
    Concernant les performances, certains semblent confondre optimisation et efficacité. Je rappelle pour ceux qui auraient oublié que l'optimisation prématurée est une des plus mauvaises choses qui peuvent arriver dans un projet.
    Il est difficile de pas etre d'accord avec ce que tu dis

    Il n'empeche, que quand on voit un bout de code de complexite polynomiale voire exponentielle, et qui risque d'etre un enorme goulet d'etranglement (le distinct que pviallate a ecrit a titre d'exemple), autant prendre les devant et le lineariser si possible. Faire le choix entre un dico et une liste pour un cache ou un intermediaire de calcul, par exemple, me semble important C'est du domaine du design, pas de l'optimisation.
    Apres, je maitrise pas suffisamment Linq pour savoir si sa syntaxe claire se fait a un cout en perf negligeable dans tous les cas.

  2. #22
    Membre Expert Avatar de Guulh
    Homme Profil pro
    Inscrit en
    Septembre 2007
    Messages
    2 160
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2007
    Messages : 2 160
    Par défaut
    Citation Envoyé par olibara Voir le message
    Mais d'apres ce que tu lis là crois tu que ca peut peut me rendre la liste des ID distinct de ma liste ?

    A mon avis non
    Bah ? Pourquoi ca ferait pas ce pour quoi c'est fait ?

  3. #23
    Membre expérimenté
    Profil pro
    Mangeur de gauffre
    Inscrit en
    Octobre 2007
    Messages
    4 413
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Mangeur de gauffre

    Informations forums :
    Inscription : Octobre 2007
    Messages : 4 413
    Par défaut
    Bonsoir

    A l'issue de ce beau et grand debat, quelqu'un peut il me dire

    1- Comment faire pour utiliser un dictionnaire : j'ai toujours pas compris comment ca marche

    En gros je percoit que c'est un peu comme mon tableau de pointeur en C

    Dans l'exemple de pvialatte
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Dictionary<int, int>();
    c'est quoi le <int,int> ?
    A quoi sert le Pourquoi 0 ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    static int CountDico(List<Machin> list)
    {
        var dico = new Dictionary<int, int>();
        foreach (Machin tmp in list) dico[tmp.Id] = 0;
        return dico.Keys.Count;
    }
    2- Est il possible de copier une liste autrement qu'en parcourant tous les élements.

  4. #24
    Membre expérimenté
    Profil pro
    Mangeur de gauffre
    Inscrit en
    Octobre 2007
    Messages
    4 413
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Mangeur de gauffre

    Informations forums :
    Inscription : Octobre 2007
    Messages : 4 413
    Par défaut
    Citation Envoyé par Guulh Voir le message
    Bah ? Pourquoi ca ferait pas ce pour quoi c'est fait ?
    J'ai essayé en lui donnant un IEqualityComparer

    Mais je ne sais pas comment caster ce qu'il me rends,

    Je croyais pouvoir caster sur une Liste de meme type mais je recois une insulte

    System.InvalidCastException was unhandled
    Message="Unable to cast object of type '<DistinctIterator>d__80`1[Recutex.ReadCPRues+Rue]' to type 'System.Collections.Generic.List`1[Recutex.ReadCPRues+Rue]'."

  5. #25
    Membre Expert Avatar de Guulh
    Homme Profil pro
    Inscrit en
    Septembre 2007
    Messages
    2 160
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2007
    Messages : 2 160
    Par défaut
    L'utilisation du dico que je t'ai montree n'est pas standard. Elle sert juste a pallier le manque de Set en C#2.

    Un Dictionary correspond a une map de la STL C++ (c'est loin d'etre neuf, comme bestiau, donc) ; c'est un conteneur associatif, qui associe des valeurs a des cles. Je vais pas te faire un tuto, mais en deux mots :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Dictionary<string, Machin> dico = new Dictionary<string, Machin>(); // ici, les cles sont de type int, les valeurs de type Machin
    dico["a"] = unMachin;
    dico["hehe"] = unAutreMachin;
    dico.ContainsKey("hehe"); // renvoie true
    Machin m = dico["hehe"]; // m == unAutreMachin
    Machin m2 = dico["hoho"]; // pete une exception car le dico n'a pas la cle "hoho"
    En C++, un set est une map dont on ignore les valeurs. C'est par definition un conteneur dont tous les elements sont distincts. Il n'y a pas d'equivalent en C#2, manque comblé en C#3.5 avec le HashSet.

    L'insertion dans un dico se base sur un IEqualityComparer que tu peux specifier si celui par defaut ne convient pas (par exemple, ci dessus, on aurait pu filer un equalitycomparer qui ignore la casse des chaines). Elle est quasi instané (elle se base sur le HashCode) ; l'acces est lui aussi quasi instantané. Par contre, la notion d'ordre n'a pas de sens. Le SortedDictionary, lui, a un iterateur sur les paires cle-valeur qui fournit les paires cles-valeur dans l'ordre, au prix d'un cout d'insertion (et peut etre d'acces, j'ai pas verifie), plus élevé.

  6. #26
    Membre Expert Avatar de Guulh
    Homme Profil pro
    Inscrit en
    Septembre 2007
    Messages
    2 160
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2007
    Messages : 2 160
    Par défaut
    Citation Envoyé par olibara Voir le message
    System.InvalidCastException was unhandled
    Message="Unable to cast object of type '<DistinctIterator>d__80`1[Recutex.ReadCPRues+Rue]' to type 'System.Collections.Generic.List`1[Recutex.ReadCPRues+Rue]'."
    Parce que ce que renvoie une requete Linq n'est pas une liste. Je suppose que c'est un Ienumerable d'un type anonyme, mais je laisse plus competent que moi te repondre

    Ah, et sinon, pour cloner une liste :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    List<Machin> newListe = new List<Machin>(oldListe);

  7. #27
    Membre expérimenté
    Profil pro
    Mangeur de gauffre
    Inscrit en
    Octobre 2007
    Messages
    4 413
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Mangeur de gauffre

    Informations forums :
    Inscription : Octobre 2007
    Messages : 4 413
    Par défaut
    Hou Hou Guulh

    C'est pas une requete linq que je fais !!!
    C'est une methode Distinct() sur une liste

    Dont je parle depuis le debut mais que seul stormimonn a relevé


    En bref

    1- Oui ca marche (comment je ne sais pas)
    2- La cast est quand meme bizarre

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
          ReadCPRues.CompareRuesEqual EqualID = new ReadCPRues.CompareRuesEqual();
     
          List<ReadCPRues.Rue> r1 = new List<ReadCPRues.Rue>();
    //      r1 = (List < ReadCPRues.Rue > )Rues.Distinct(EqualID );  // marche pas
          ReadCPRues.Rue[] ttt = Rues.Distinct(EqualID).ToArray(); // ca marche ??

  8. #28
    Membre expérimenté
    Profil pro
    Mangeur de gauffre
    Inscrit en
    Octobre 2007
    Messages
    4 413
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Mangeur de gauffre

    Informations forums :
    Inscription : Octobre 2007
    Messages : 4 413
    Par défaut
    Citation Envoyé par Guulh Voir le message
    L'insertion dans un dico se base sur un IEqualityComparer que tu peux specifier si celui par defaut ne convient pas (par exemple, ci dessus, on aurait pu filer un equalitycomparer qui ignore la casse des chaines). Elle est quasi instané (elle se base sur le HashCode) ; l'acces est lui aussi quasi instantané. Par contre, la notion d'ordre n'a pas de sens. Le SortedDictionary, lui, a un iterateur sur les paires cle-valeur qui fournit les paires cles-valeur dans l'ordre, au prix d'un cout d'insertion (et peut etre d'acces, j'ai pas verifie), plus élevé.
    Donc un dictionary ou un Hashset c'est a peu pres la meme chose et c'est pas trié par nature

    Bon je dvais essayer de comprendre comment marche un sorted dictionary

    Mais le Distinct() de la List<> semble combiner tout ca

  9. #29
    Membre Expert Avatar de Guulh
    Homme Profil pro
    Inscrit en
    Septembre 2007
    Messages
    2 160
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2007
    Messages : 2 160
    Par défaut
    Citation Envoyé par olibara Voir le message
    C'est pas une requete linq que je fais !!!
    C'est une methode Distinct() sur une liste
    C'est pas une requête linq, mais presque Les requêtes Linq ne sont qu'une syntaxe (agréable, certes) sur un enchaînement plus ou moins complexe d'appels de méthodes de ce style. En l'occurence, Distinct() est l'une des extension methods rajoutées avec le fx 3.5 : http://msdn.microsoft.com/en-us/library/bb348436.aspx
    Distinct est une méthode statique qui prend en entrée un IEnumerable et qui en sort un autre. En fonctions de tes besoins, tu peux soit te contenter de cet IEnumerable, soit le convertir dans un format qui te va bien. Si tu veux le transformer en liste, ça tombe bien, parce que List<T> a un constructeur qui prend un IEnumerable<T> en paramètre.

  10. #30
    Membre expérimenté
    Profil pro
    Mangeur de gauffre
    Inscrit en
    Octobre 2007
    Messages
    4 413
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Mangeur de gauffre

    Informations forums :
    Inscription : Octobre 2007
    Messages : 4 413
    Par défaut
    Bonjour,

    Je me permet de revenir à l'origine de cette discussion qui a ouvert pas mal de sujet

    Le but initial est d'extraire uun count et une liste d'elements distinct d'une liste.
    J'avais vu la methode Distinct mais personne sauf Stormimon n'a relevé cette chose

    J'expose donc la solution a laquelle je suis arrivé


    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
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    // Declaration de ma classe
        public class Rue
        {
          private int _id;
          private string _nom;
          public int Id
          {
            get { return _id; }
            set { _id = value; }
          }
          public string Nom
          {
            get { return _nom; }
            set { _nom = value; }
          }
        }
     
     
    // declaration d'un compareur d'egalité
        public class CompareRuesEqual : IEqualityComparer<Rue>
        {
          public bool Equals(Rue x, Rue y)
          {
            return (x.Id == y.Id);
          }
     
          public int GetHashCode(Rue obj)
          {
            return obj.Id;  // TODO verifier la pertinence
          }
        };
     
     
     
    // Recherche des distinct
     
        ReadCPRues.CompareRuesEqual isEqual = new ReadCPRues.CompareRuesEqual();
     
        List<ReadCPRues.Rue> Rdistinct = new List<ReadCPRues.Rue>();
        Rdistinct = (List<ReadCPRues.Rue>)Rues.Distinct(isEqual).ToList();
        ReadCPRues.Rue[] ttt = Rues.Distinct(isEqual).ToArray();
    Je suppose que de maniere interne la methode distinct cree son dico ou son hashset mais je ne sais pas si c'est plus performant que de travailler avec Linq ou a la main sur une liste triée

    Ce qui m'interpelle encore c'est de devoir passer par les methodes ToList ou ToArray pour assigner le resultat

    Et ce que je ne sais toujours pas c'est COMMENT proprement faire une copie indépendante de liste : je pense que je vais ouvrir une discussion sur ce sujet simple

  11. #31
    Rédacteur
    Avatar de SaumonAgile
    Homme Profil pro
    Team leader
    Inscrit en
    Avril 2007
    Messages
    4 028
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Team leader
    Secteur : Conseil

    Informations forums :
    Inscription : Avril 2007
    Messages : 4 028
    Par défaut
    Citation Envoyé par Guulh Voir le message
    Parce que ce que renvoie une requete Linq n'est pas une liste. Je suppose que c'est un Ienumerable d'un type anonyme, mais je laisse plus competent que moi te repondre
    Les requêtes LINQ to Objects travaillent sur des IEnumerable typés. Le type n'est anonyme que dans le cas où ton select est un new { MaPropriété = valeur } et non pas un type classique.

    Je détaille tout ici.
    Besoin d'un MessageBox amélioré ? InformationBox pour .NET 1.1, 2.0, 3.0, 3.5, 4.0 sous license Apache 2.0.

    Bonnes pratiques pour les accès aux données
    Débogage efficace en .NET
    LINQ to Objects : l'envers du décor

    Mon profil LinkedIn - MCT - MCPD WinForms - MCTS Applications Distribuées - MCTS WCF - MCTS WCF 4.0 - MCTS SQL Server 2008, Database Development - Mon blog - Twitter

  12. #32
    Membre Expert Avatar de Guulh
    Homme Profil pro
    Inscrit en
    Septembre 2007
    Messages
    2 160
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2007
    Messages : 2 160
    Par défaut
    Citation Envoyé par olibara Voir le message
    Le but initial est d'extraire uun count et une liste d'elements distinct d'une liste.
    Comme je le disais hier, si l'ordre ne t'importe pas, parcourir ta liste en ajoutant les IDs dans un HashSet répond à ton problème.

    Pour ce qui est de cloner une liste, regarde mon post d'hier à 00:33.

  13. #33
    Membre expérimenté
    Profil pro
    Mangeur de gauffre
    Inscrit en
    Octobre 2007
    Messages
    4 413
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Mangeur de gauffre

    Informations forums :
    Inscription : Octobre 2007
    Messages : 4 413
    Par défaut
    Salut Guulh

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    List<Machin> newListe = new List<Machin>(oldListe);
    J'avais essayé ca tout au debut, ca semblait tres facile

    Mais en realité ca reste la MEME liste si tu change une valeur dans newListe elle changera AUSSI dans oldliste

    Et pour l'ordre oui ca a de l'importance et c'est la raison pour laquelle j'avais dis plusieurs fois que le hashset ne me semblait pas approprié

  14. #34
    Rédacteur
    Avatar de The_badger_man
    Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2005
    Messages
    2 745
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 745
    Par défaut
    Citation Envoyé par olibara Voir le message
    Mais en realité ca reste la MEME liste si tu change une valeur dans newListe elle changera AUSSI dans oldliste
    C'est une liste différente mais reférençant les mêmes objets.
    Les règles du forum
    Le trio magique : FAQ + Cours + fonction rechercher
    Mes articles
    Pas de questions par messages privés svp

    Software is never finished, only abandoned.

  15. #35
    Membre expérimenté
    Profil pro
    Mangeur de gauffre
    Inscrit en
    Octobre 2007
    Messages
    4 413
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Mangeur de gauffre

    Informations forums :
    Inscription : Octobre 2007
    Messages : 4 413
    Par défaut
    Salut

    Donc si je comprends bien cette "autre" liste n'est qu'une liste de reference (pointeurs en C) sur les elements constituant ma premiere liste

    Donc
    1- Pas question d'alterer un element de l'une sans avoir des repercussion sur l'autre
    2 Par contre, je Trie cette "autre" liste la premiere liste ne sera pas affectée ?, je pourrais donc ainsi avoir plusieurs tris sur la meme liste ?

  16. #36
    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 : 43
    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 olibara Voir le message
    1- Pas question d'alterer un element de l'une sans avoir des repercussion sur l'autre
    C'est ça. La liste contient des références vers les objets, pas des copies des objets.
    Citation Envoyé par olibara Voir le message
    2 Par contre, je Trie cette "autre" liste la premiere liste ne sera pas affectée ?, je pourrais donc ainsi avoir plusieurs tris sur la meme liste ?
    Tout à fait

  17. #37
    Membre émérite
    Inscrit en
    Octobre 2006
    Messages
    587
    Détails du profil
    Informations personnelles :
    Âge : 38

    Informations forums :
    Inscription : Octobre 2006
    Messages : 587
    Par défaut
    Citation Envoyé par olibara Voir le message
    C'est pas une requete linq que je fais !!!
    C'est une methode Distinct() sur une liste
    C'est la même chose. LINQ c'est avant tout les méthodes d'extensions et Distinct en fait partie. Le langage LINQ ne fait qu'utiliser ces méthodes d'extensions et rien de plus pour proposer un modèle plus simple.

Discussions similaires

  1. [langage] Supprimer un élément dans une liste
    Par myjuna dans le forum Langage
    Réponses: 15
    Dernier message: 06/08/2014, 11h49
  2. Random element dans liste sharepoint
    Par spantemonium dans le forum SharePoint
    Réponses: 0
    Dernier message: 10/06/2008, 11h14
  3. Pb d'ajout d'element dans un liste
    Par profx dans le forum Général JavaScript
    Réponses: 17
    Dernier message: 27/02/2007, 17h49
  4. occurences d'un element dans une liste (algorithme)
    Par kespy13 dans le forum Algorithmes et structures de données
    Réponses: 25
    Dernier message: 16/02/2006, 00h18
  5. Recherche Element dans une liste
    Par hellodelu dans le forum ASP
    Réponses: 7
    Dernier message: 19/08/2005, 10h56

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