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 :

Dictionnaire à 2 clef


Sujet :

Framework .NET

  1. #1
    Membre éprouvé Avatar de anthyme
    Homme Profil pro
    Inscrit en
    Mars 2004
    Messages
    1 559
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2004
    Messages : 1 559
    Points : 1 257
    Points
    1 257
    Par défaut Dictionnaire à 2 clef
    Et oui je reviens avec mes idées bizarres

    J'aimerai savoir si il existe une implémentation d'un dictionnaire à 2 clef.
    en gros on ferait dict.Get("clef1", "clef2") et dict.Set("clef1","clef2", value)

    En gros le but serai d'avoir la représentation d'un tableau ou chaque colone serai associé a une des premières clef (dans mon cas une date) et chaque ligne associé une des deuxièmes clef (un objet business) et donc chaque cellule contient une valeur correspondant avec une des premières et une des deuxièmes clef (un peu comme des coordonnées)

    Comment représenter cela efficacement ? (et pas de datatable non typé hein ! )

    Merci

  2. #2
    Rédacteur
    Avatar de dev01
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    2 451
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 2 451
    Points : 6 017
    Points
    6 017
    Par défaut
    Citation Envoyé par anthyme Voir le message
    Et oui je reviens avec mes idées bizarres

    J'aimerai savoir si il existe une implémentation d'un dictionnaire à 2 clef.
    en gros on ferait dict.Get("clef1", "clef2") et dict.Set("clef1","clef2", value)

    En gros le but serai d'avoir la représentation d'un tableau ou chaque colone serai associé a une des premières clef (dans mon cas une date) et chaque ligne associé une des deuxièmes clef (un objet business) et donc chaque cellule contient une valeur correspondant avec une des premières et une des deuxièmes clef (un peu comme des coordonnées)

    Comment représenter cela efficacement ? (et pas de datatable non typé hein ! )

    Merci
    Deux solutions : Soit tu écrit ta classe de gestion de grille (type excel) soit tu utilises un Dictionnary<int, Dictionnary<int, object>>
    - MVP C#
    -Tout problème a une solution, le vrai problème est de trouver la solution .....
    - Linux & mono : l'avenir

  3. #3
    Membre éprouvé Avatar de anthyme
    Homme Profil pro
    Inscrit en
    Mars 2004
    Messages
    1 559
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2004
    Messages : 1 559
    Points : 1 257
    Points
    1 257
    Par défaut
    Mouarf !

    Bon je vais réfléchir la dessus mais bon mes collègues me poussent a faire une datatable ... moi qui espérait sortir une solution de mon chapeau magique

    Merci pour les idées !

  4. #4
    Membre chevronné
    Profil pro
    Inscrit en
    Février 2005
    Messages
    1 273
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 1 273
    Points : 2 202
    Points
    2 202
    Par défaut
    Tiens, moi j'utilise ça; ca prends moins de temps qu'une table, c'est plus léger;

    J'arrive en moyenne à faire du 100*1000000.

    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
    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
     
    public class CompositeKeyDictionary<T,U,V> 
        {
            private Dictionary<T, Dictionary<U, V>> _grid;
     
            public CompositeKeyDictionary()
            {
                _grid = new Dictionary<T, Dictionary<U, V>>();
     
            }
     
            public IEnumerable<V> GetThirdLevel(T k1)
            {
                if (_grid.ContainsKey(k1))
                {
                    return _grid[k1].Values;
                }
                return null;
            }
     
            public IDictionary<U,V> GetRecords(T k1)
            {
                if (_grid.ContainsKey(k1))
                {
                    return _grid[k1];
                }
                return null;
            }
     
            public void ClearRecords(T k1)
            {
                if (_grid.ContainsKey(k1))
                {
                    _grid[k1].Clear();
                }
            }
     
            public void AddRecord(T k1,U k2,V k3)
            {
                Dictionary<U, V> kvp;
                if (_grid.ContainsKey(k1))
                {
                    kvp = _grid[k1];
                    kvp.Add(k2, k3);
     
                }
                else
                {
                    kvp = new Dictionary<U, V>();
                    kvp.Add(k2, k3);
                    _grid.Add(k1, kvp);
     
                }
     
            }
     
            public void RemoveRecord(T k1)
            {
                _grid.Remove(k1);
            }
     
            public void Clear()
            {
                _grid.Clear();
            }
     
     
     
        }

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

    Informations forums :
    Inscription : Septembre 2007
    Messages : 2 160
    Points : 2 925
    Points
    2 925
    Par défaut
    Si tu n'as besoin que des cellules et jamais des lignes / colonnes, un dico simple suffit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Dictionary<Pair<string, string>, T>
    Où Pair est une struct toute bête à deux valeurs (le fx 3.5 a probablement ça quelque part), qui doit même pas avoir besoin de surcharger IEquatable parce qu'il me semble déjà que deux structs sont égales si tous ses champs sont égaux.
    ಠ_ಠ

  6. #6
    Membre chevronné
    Profil pro
    Inscrit en
    Février 2005
    Messages
    1 273
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 1 273
    Points : 2 202
    Points
    2 202
    Par défaut
    Non, c'est un peu lourd à faire en fait si tu veux une structure relationnelle.

    En fait tu es obligé de créer tes propres critéres de comparaison.

    Au début j'avais utilisé un objet<T,U> qui recevait deux params et constitue la clef, mais au bout d'un moment, si tu encapsules ça dans un objet, tu vas arriver au moment où tu vas faire un truc genre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    var _busobject=(BusinessObject)ObjectFactory.GetBusinessObject(25);
    var _assertion=new CompositeKey<DateTime,BusinessObject>(DateTime.Parse("01/01/2008"),_busobject);
    
    if (_dic.contains(_assertion))
    {
    ...
    }
    Et là, tu es obligé de spécifier une modalité de comparaison de la clef pour un couple donné.

    J'avais à l'époque utilisé le moteur d'évaluation de spring et une instanciation par string[] des propriétés à contrôler, mais là, ça devient beaucoup trop lours à traiter en fait.

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

    Informations forums :
    Inscription : Septembre 2007
    Messages : 2 160
    Points : 2 925
    Points
    2 925
    Par défaut
    Bah si tu fais un héritage ou que tu encapsules, comme suggéré dans le post initial, avec deux méthodes get et set du style dict.Get("clef1", "clef2") et dict.Set("clef1","clef2", value), je vois pas le souci. La verbosioté est masquée dans ces deux méthodes.
    ಠ_ಠ

  8. #8
    Expert éminent
    Avatar de smyley
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    6 270
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 6 270
    Points : 8 344
    Points
    8 344
    Par défaut
    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
     
    public class CompositKey<T, K> : IEquatable<CompositKey<T, K>> where T:IEquatable<T> where K:IEquatable<K>
            {
                public CompositKey(T key1, K key2)
                {
                    Key1 = key1;
                    Key2 = key2;
     
                    if (Key1 == null || Key2 == null)
                        throw new ArgumentNullException(Key1 == null ? "Key1" : "Key2");
                }
     
                public virtual T Key1 { get; protected set; }
                public virtual K Key2 { get; protected set; }
     
                public override int GetHashCode()
                {
                    return (int)(Key1.GetHashCode() + Key2.GetHashCode());
                }
     
                #region IEquatable<CompositKey<T,K>> Membres
     
                public bool Equals(CompositKey<T, K> other)
                {
                    if (ReferenceEquals(other,null))
                        return false;
                    else
                    {
                        bool c1, c2;
     
                        if (Key1 == null)
                            c1 = other.Key1 == null;
                        else
                            c1 = Key1.Equals(other.Key1);
     
                        if (Key2 == null)
                            c2 = other.Key2 == null;
                        else
                            c2 = Key2.Equals(other.Key2);
     
                        return c1 && c2;
                    }
                }
     
                #endregion
     
                public static bool operator ==(CompositKey<T, K> a, CompositKey<T, K> b)
                {
                    if (ReferenceEquals(a, null))
                        return ReferenceEquals(b, null);
                    else
                        return a.Equals(b);
                }
     
                public static bool operator !=(CompositKey<T, K> a, CompositKey<T, K> b)
                {
                    if (ReferenceEquals(a, null))
                        return !ReferenceEquals(b, null);
                    else
                        return !a.Equals(b);
                }
            }
     
            /* ET LE TEST !! */
            public Form1()
            {
                Dictionary<CompositKey<string, string>, string> test 
                    = new Dictionary<CompositKey<string, string>, string>();
                test[new CompositKey<string, string>("A", "B")] = "chat";
                test[new CompositKey<string, string>("A", "C")] = "chien";
     
                var gh = new CompositKey<string, string>("A", "C");
                MessageBox.Show(gh.Equals(new CompositKey<string, string>("A", "C")).ToString());
                MessageBox.Show((gh == (new CompositKey<string, string>("A", "C"))).ToString());
     
                MessageBox.Show(test.ContainsKey(new CompositKey<string, string>("A", "B")).ToString());
                MessageBox.Show(test.ContainsKey(new CompositKey<string, string>("A", "C")).ToString());
                MessageBox.Show(test.ContainsKey(new CompositKey<string, string>("D", "B")).ToString());
     
                MessageBox.Show(test[new CompositKey<string, string>("A", "B")]);
           }

    J'ai juste un doute : il se passe quoi si deux clefs ont le même Hash ?
    edit: ah non c'est bon. S'il y a collision des HashCode, la méthode Equals est appelée donc ça marche bien.

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

    Informations forums :
    Inscription : Septembre 2007
    Messages : 2 160
    Points : 2 925
    Points
    2 925
    Par défaut
    C'est un peu too much, non, une classe pour stocker deux champs, constants qui plus est ?

    Et il me semble que les structs ont automatiquement un Equals et un GetHashCode qui prennent en compte tous les champs qu'elles contiennent.

    Une struct CompositKey se résume alors à ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    public struct CompositKey<T, K> : IEquatable<CompositKey<T, K>>
    {
      public CompositKey(T key1, K key2)
      {
        Key1 = key1;
        Key2 = key2;
      }
      public T Key1 { get; private set; }
      public K Key2 { get; private set; }
      public bool Equals(CompositKey<T, K> other)
      {
        return this == other;
      }
    }
    Pas testé mais ça devrait marcher. Et faire moins mal au GC
    ಠ_ಠ

  10. #10
    Expert éminent
    Avatar de smyley
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    6 270
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 6 270
    Points : 8 344
    Points
    8 344
    Par défaut
    Ton code marche pas
    Et c'est pas vraiment too much si tu retires les override pour les opérateurs == et != (c'est juste un effet pour pouvoir comparer deux clefs sans se casser la tête avec ==)

    Après le code marche. C'est sur que si on crée beaucoup de clefs ça pourrai faire le GC râler mais vu la taille d'une clef (en gros une dizaine d'octets) ça restera négligeable.

    Pour la struct j'y avais pas pensé, mais bon, ça revient un peut au même (vu qu'on ne va pas avoir souvent à écrire le code de CompositKey : c'est une classe dans un coin dont tout ce que l'on va savoir c'est que ça s'écrit CompositKey<T,K>).

  11. #11
    Membre averti
    Inscrit en
    Décembre 2008
    Messages
    256
    Détails du profil
    Informations personnelles :
    Âge : 47

    Informations forums :
    Inscription : Décembre 2008
    Messages : 256
    Points : 311
    Points
    311
    Par défaut
    Citation Envoyé par Guulh Voir le message
    Et il me semble que les structs ont automatiquement un Equals et un GetHashCode qui prennent en compte tous les champs qu'elles contiennent.
    T'es certain de ça ?

    Parce que si c'est vrai, je pense que je vais transformer ma classe CompositeKey "maison" par une struct
    Il y a toujours au moins deux solutions à un problème.

    http://software-design-development.blogspot.com/

  12. #12
    Membre chevronné
    Profil pro
    Inscrit en
    Février 2005
    Messages
    1 273
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 1 273
    Points : 2 202
    Points
    2 202
    Par défaut
    Je connais déjà la réponse.

    En plus, vive les stack overflows...

  13. #13
    Membre averti
    Inscrit en
    Décembre 2008
    Messages
    256
    Détails du profil
    Informations personnelles :
    Âge : 47

    Informations forums :
    Inscription : Décembre 2008
    Messages : 256
    Points : 311
    Points
    311
    Par défaut
    Citation Envoyé par B.AF Voir le message
    Je connais déjà la réponse.

    En plus, vive les stack overflows...
    Heu, non pas franchement. J'ai récemment du me développer une classe MyFieldKey pour utiliser des dictionnaires de MyField parce que j'ai 2 niveau de clé : un string et un entier, mais je trouve ma construction super lourde (j'ai été obligé de redéfinir les méthodes Equals() et GetHashCode(), ce qui ne me plaît pas trop) donc je cherche comment la changer, c'est pour ça que je suis ce fil de discussion avec intérêt.
    Il y a toujours au moins deux solutions à un problème.

    http://software-design-development.blogspot.com/

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

    Informations forums :
    Inscription : Septembre 2007
    Messages : 2 160
    Points : 2 925
    Points
    2 925
    Par défaut
    Citation Envoyé par Gold Bug Voir le message
    T'es certain de ça ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    struct Bidule { public int I, J; }
     
    void f()
    {
      Bidule b1 = new Bidule();
      Bidule b2 = new Bidule(); // ici, b1.Equals(b2) est true
      b1.I = 5; // b1.Equals(b2) est false
      b2.I = 5; // b1.Equals(b2) est true
    }
    Donc oui, pas besoin de surcharger Equals. Là où je me suis gourré, c'est que l'operator== est pas défini par défaut, et qu'il faut le surcharger s'il on veut s'en servir.

    smyley : oui c'est pas bien important, mais les pauvres structs sont utiles dans si peu de cas qu'il faut pas leur retirer leurs quelques instants de gloire
    ಠ_ಠ

  15. #15
    Membre averti
    Inscrit en
    Décembre 2008
    Messages
    256
    Détails du profil
    Informations personnelles :
    Âge : 47

    Informations forums :
    Inscription : Décembre 2008
    Messages : 256
    Points : 311
    Points
    311
    Par défaut
    Citation Envoyé par Guulh Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    struct Bidule { public int I, J; }
     
    void f()
    {
      Bidule b1 = new Bidule();
      Bidule b2 = new Bidule(); // ici, b1.Equals(b2) est true
      b1.I = 5; // b1.Equals(b2) est false
      b2.I = 5; // b1.Equals(b2) est true
    }
    Donc oui, pas besoin de surcharger Equals. Là où je me suis gourré, c'est que l'operator== est pas défini par défaut, et qu'il faut le surcharger s'il on veut s'en servir.

    smyley : oui c'est pas bien important, mais les pauvres structs sont utiles dans si peu de cas qu'il faut pas leur retirer leurs quelques instants de gloire
    Ca marche pareil si J est de type String ?
    Il y a toujours au moins deux solutions à un problème.

    http://software-design-development.blogspot.com/

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

    Informations forums :
    Inscription : Septembre 2007
    Messages : 2 160
    Points : 2 925
    Points
    2 925
    Par défaut
    Citation Envoyé par Gold Bug Voir le message
    Ca marche pareil si J est de type String ?
    Oui.
    ಠ_ಠ

  17. #17
    Membre éprouvé Avatar de anthyme
    Homme Profil pro
    Inscrit en
    Mars 2004
    Messages
    1 559
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2004
    Messages : 1 559
    Points : 1 257
    Points
    1 257
    Par défaut
    woua j'ai déchainé les passions

Discussions similaires

  1. Réponses: 0
    Dernier message: 26/05/2014, 12h23
  2. Réponses: 18
    Dernier message: 04/11/2011, 10h24
  3. Réponses: 27
    Dernier message: 06/04/2010, 17h23
  4. Réponses: 2
    Dernier message: 13/10/2006, 23h35
  5. INSERT avec procédure stockée / Clef de type AutoInc
    Par bgdelphi dans le forum Bases de données
    Réponses: 5
    Dernier message: 18/10/2003, 18h30

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