79 votes

La meilleure implémentation pour la structure de données de la paire clé-valeur ?

J'ai un peu farfouillé dans le C# ces derniers temps, et toutes les collections génériques me laissent un peu perplexe. Imaginons que je veuille représenter une structure de données où la tête de l'arbre est une paire clé-valeur, et où il y a une liste optionnelle de paires clé-valeur en dessous (mais pas plus de niveaux que ceux-ci). Est-ce que cela conviendrait ?

public class TokenTree
{
    public TokenTree()
    {
        /* I must admit to not fully understanding this,
         * I got it from msdn. As far as I can tell, IDictionary is an
         * interface, and Dictionary is the default implementation of
         * that interface, right?
         */
        SubPairs = new Dictionary<string, string>();
    }

    public string Key;
    public string Value;
    public IDictionary<string, string> SubPairs;
}

Ce n'est qu'un simple shunt pour faire circuler les données.

141voto

Adam Haile Points 12576

Il existe un véritable type de données appelé KeyValuePair, à utiliser comme suit

KeyValuePair<string, string> myKeyValuePair = new KeyValuePair<string,string>("defaultkey", "defaultvalue");

1 votes

Cela fonctionne très bien avec une déclaration "using" (similaire à l'ancien typedef) afin d'économiser de la saisie et de rendre tout plus clair. Si vous utilisez constamment, par exemple, la paire (string, string).

8 votes

KeyValuePair<string, string> NOM_HERE = new KeyValuePair<string,string>("defaultkey", "defaultvalue") ;

1 votes

Pour développer le commentaire de @AndreasReiff : using NameValuePair = System.Collections.Generic.KeyValuePair<string, string>; en haut de chaque fichier qui nécessite un (string, string) struct. Bien que j'ai trouvé plus pratique de créer un class NameValuePair dans mon espace de nom : public class NameValuePair { KeyValuePair<string, string> it; public NameValuePair( string name, string value ) { it = new KeyValuePair<string, string>( name, value ); } public string Name { get { return it.Key; } } public string Value { get { return it.Value; } } }

14voto

Jon Limjap Points 46429

Il est possible d'utiliser l'objet Dictionary tel quel, puis de l'étendre avec vos propres modifications :

public class TokenTree : Dictionary<string, string>
{
    public IDictionary<string, string> SubPairs;
}

Cela vous donne l'avantage de ne pas avoir à appliquer les règles d'IDictionary pour votre clé (par exemple, l'unicité de la clé, etc.).

Et oui, vous avez bien compris le concept du constructeur :)

7voto

Shaun Austin Points 2512

Je pense que ce que vous recherchez (en tant qu'implémentation littérale de votre question), est :

public class TokenTree
{
    public TokenTree()
    {
        tree = new Dictionary<string, IDictionary<string,string>>();
    }

    IDictionary<string, IDictionary<string, string>> tree; 
}

Vous avez en fait parlé d'une "liste" de valeurs clés dans votre question, vous pourriez donc intervertir l'élément interne de la liste avec l'élément externe. IDictionary avec un :

IList<KeyValuePair<string, string>>

5voto

Coincoin Points 12823

Il existe un type intégré KeyValuePair. En fait, c'est à ce type que l'IDictionary vous donne accès lorsque vous y itérez.

De plus, cette structure est loin d'être un arbre, trouver un nom plus représentatif pourrait être un bon exercice.

2voto

Lasse V. Karlsen Points 148037

@ Jay Mooney : Une classe de dictionnaire générique dans .NET est en fait une table de hachage, mais avec des types fixes.

Le code que vous avez montré ne devrait convaincre personne d'utiliser Hashtable au lieu de Dictionary, puisque les deux morceaux de code peuvent être utilisés pour les deux types.

Pour hashtable :

foreach(object key in h.keys)
{
     string keyAsString = key.ToString(); // btw, this is unnecessary
     string valAsString = h[key].ToString();

     System.Diagnostics.Debug.WriteLine(keyAsString + " " + valAsString);
}

Pour le dictionnaire :

foreach(string key in d.keys)
{
     string valAsString = d[key].ToString();

     System.Diagnostics.Debug.WriteLine(key + " " + valAsString);
}

Et de même pour l'autre avec KeyValuePair, il suffit d'utiliser la version non générique pour Hashtable, et la version générique pour Dictionary.

C'est donc aussi simple dans les deux cas, mais Hashtable utilise Object à la fois pour la clé et la valeur, ce qui signifie que vous allez mettre en boîte tous les types de valeurs et que vous n'avez pas de sécurité de type, alors que Dictionary utilise des types génériques et est donc meilleur.

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