Dictionnaire c # Comment append plusieurs valeurs pour une clé unique?

J’ai créé un object dictionnaire

Dictionary<string, List> dictionary = new Dictionary<string,List>(); 

Je veux append des valeurs de chaîne à la liste de chaînes pour une clé unique donnée. Si la clé n’existe pas déjà, je dois append une nouvelle clé. List n’est pas prédéfinie, je veux dire que je n’ai créé aucun object de liste, puis fourni au dictionary.Add("key",Listname) . Comment créer dynamicment cet object liste dans le dictionary.Add("key",Listname) puis ajoutez des chaînes à cette liste. Si je dois append 100 clés, dois-je créer 100 listes avant d’exécuter une instruction dictionary.Add et dois-je pédaler le contenu de ces listes?

Je vous remercie.

Mise à jour: vérifiez l’existence à l’aide de TryGetValue pour effectuer une seule recherche dans le cas où vous avez la liste:

 List list; if (!dictionary.TryGetValue("foo", out list)) { list = new List(); dictionary.Add("foo", list); } list.Add(2); 

Original: vérifiez l’existence et ajoutez une fois, puis entrez le dictionnaire pour obtenir la liste et ajoutez-la à la liste normalement:

 var dictionary = new Dictionary>(); if (!dictionary.ContainsKey("foo")) dictionary.Add("foo", new List()); dictionary["foo"].Add(42); dictionary["foo"].AddRange(oneHundredInts); 

Ou List comme dans votre cas.

En passant, si vous savez combien d’éléments vous allez append à une collection dynamic telle que List , privilégiez le constructeur qui prend la capacité de liste initiale: new List(100); .

Cela récupérera la mémoire requirejse pour satisfaire la capacité spécifiée dès le départ , au lieu d’attraper de petits morceaux chaque fois qu’elle commence à se remplir. Vous pouvez faire la même chose avec les dictionnaires si vous savez que vous avez 100 clés.

Si j’ai compris ce que tu veux:

 dictionary.Add("key", new List()); 

plus tard…

 dictionary["key"].Add("ssortingng to your list"); 
 Dictionary> dictionary = new Dictionary>(); foreach(ssortingng key in keys) { if(!dictionary.ContainsKey(key)) { //add dictionary.Add(key, new List()); } dictionary[key].Add("theSsortingng"); } 

Si la clé n’existe pas, une nouvelle List est ajoutée (à l’intérieur de si). Sinon, la clé existe, ajoutez simplement une nouvelle valeur à la List sous cette clé.

Vous pouvez utiliser mon implémentation d’une carte multiple, qui dérive d’un Dictionary> . Ce n’est pas parfait, mais cela fait du bon travail.

 ///  /// Represents a collection of keys and values. /// Multiple values can have the same key. ///  /// Type of the keys. /// Type of the values. public class MultiMap : Dictionary> { public MultiMap() : base() { } public MultiMap(int capacity) : base(capacity) { } ///  /// Adds an element with the specified key and value into the MultiMap. ///  /// The key of the element to add. /// The value of the element to add. public void Add(TKey key, TValue value) { List valueList; if (TryGetValue(key, out valueList)) { valueList.Add(value); } else { valueList = new List(); valueList.Add(value); Add(key, valueList); } } ///  /// Removes first occurence of an element with a specified key and value. ///  /// The key of the element to remove. /// The value of the element to remove. /// true if the an element is removed; /// false if the key or the value were not found. public bool Remove(TKey key, TValue value) { List valueList; if (TryGetValue(key, out valueList)) { if (valueList.Remove(value)) { if (valueList.Count == 0) { Remove(key); } return true; } } return false; } ///  /// Removes all occurences of elements with a specified key and value. ///  /// The key of the elements to remove. /// The value of the elements to remove. /// Number of elements removed. public int RemoveAll(TKey key, TValue value) { List valueList; int n = 0; if (TryGetValue(key, out valueList)) { while (valueList.Remove(value)) { n++; } if (valueList.Count == 0) { Remove(key); } } return n; } ///  /// Gets the total number of values contained in the MultiMap. ///  public int CountAll { get { int n = 0; foreach (List valueList in Values) { n += valueList.Count; } return n; } } ///  /// Determines whether the MultiMap contains an element with a specific /// key / value pair. ///  /// Key of the element to search for. /// Value of the element to search for. /// true if the element was found; otherwise false. public bool Contains(TKey key, TValue value) { List valueList; if (TryGetValue(key, out valueList)) { return valueList.Contains(value); } return false; } ///  /// Determines whether the MultiMap contains an element with a specific value. ///  /// Value of the element to search for. /// true if the element was found; otherwise false. public bool Contains(TValue value) { foreach (List valueList in Values) { if (valueList.Contains(value)) { return true; } } return false; } } 

Notez que la méthode Add recherche si une clé est déjà présente. Si la clé est nouvelle, une nouvelle liste est créée, la valeur est ajoutée à la liste et la liste est ajoutée au dictionnaire. Si la clé était déjà présente, la nouvelle valeur est ajoutée à la liste existante.

Bien que presque identique à la plupart des autres réponses, je pense que c’est la manière la plus efficace et la plus concise de la mettre en œuvre. L’utilisation de TryGetValue est plus rapide que l’utilisation de ContainsKey et la réindexation dans le dictionnaire, comme le montrent d’autres solutions.

 void Add(ssortingng key, ssortingng val) { List list; if (!dictionary.TryGetValue(someKey, out list)) { values = new List(); dictionary.Add(key, list); } list.Add(val); } 

Utilisez NameValuedCollection.

Bon sharepoint départ est ici . Directement du lien.

 System.Collections.Specialized.NameValueCollection myCollection = new System.Collections.Specialized.NameValueCollection(); myCollection.Add(“Arcane”, “http://arcanecode.com”); myCollection.Add(“PWOP”, “http://dotnetrocks.com”); myCollection.Add(“PWOP”, “http://dnrtv.com”); myCollection.Add(“PWOP”, “http://www.hanselminutes.com”); myCollection.Add(“TWIT”, “http://www.twit.tv”); myCollection.Add(“TWIT”, “http://www.twit.tv/SN”); 

Lorsque vous ajoutez une chaîne, procédez différemment selon que la clé existe déjà ou non. Pour append la value chaîne pour la clé de key :

 List list; if (dictionary.ContainsKey(key)) { list = dictionary[key]; } else { list = new List(); dictionary.Add(ley, list); } list.Add(value); 

Au lieu d’utiliser un dictionnaire, pourquoi ne pas convertir en ILookup?

 var myData = new[]{new {a=1,b="frog"}, new {a=1,b="cat"}, new {a=2,b="giraffe"}}; ILookup lookup = myData.ToLookup(x => xa, x => xb); IEnumerable allOnes = lookup[1]; //enumerable of 2 items, frog and cat 

Un ILookup est une structure de données immuable qui permet plusieurs valeurs par clé. Probablement pas très utile si vous devez append des éléments à des moments différents, mais si vous avez toutes vos données à l’avance, c’est définitivement la voie à suivre.

Voici plusieurs variantes de la réponse 🙂 My en est une autre et utilise le mécanisme d’extension comme moyen commode d’exécuter (pratique):

 public static void AddToList(this IDictionary> dict, T key, U elementToList) { List list; bool exists = dict.TryGetValue(key, out list); if (exists) { dict[key].Add(elementToList); } else { dict[key] = new List(); dict[key].Add(elementToList); } } 

Ensuite, vous l’utilisez comme suit:

 Dictionary> dict = new Dictionary>(); dict.AddToList(4, "test1"); dict.AddToList(4, "test2"); dict.AddToList(4, "test3"); dict.AddToList(5, "test4"); 

Il existe un paquet NuGet Collections expérimentales Microsoft qui contient une classe MultiValueDictionary qui fait exactement ce dont vous avez besoin.

Voici un article de blog du créateur du paquet qui le décrit plus en détail.

Voici un autre article de blog si vous vous sentez curieux.

Exemple d’utilisation:

 MultiDictionary myDictionary = new MultiDictionary(); myDictionary.Add("key", 1); myDictionary.Add("key", 2); myDictionary.Add("key", 3); //myDictionary["key"] now contains the values 1, 2, and 3 

J’essayais d’append List à une clé existante dans le dictionnaire et j’ai atteint la solution suivante:

 Dictionary> NewParent = new Dictionary>(); child = new List (); child.Add('SomeData'); NewParent["item1"].AddRange(child); 

Il ne montrera aucune exception et ne remplacera pas les valeurs précédentes.