web-dev-qa-db-fra.com

Énumération de dictionnaire en C #

Comment énumérer un dictionnaire?

Supposons que j'utilise foreach() pour l'énumération dictionay. Je ne peux pas mettre à jour une paire clé/valeur dans foreach(). Alors je veux une autre méthode.

25
Ravi

Pour énumérer un dictionnaire, vous énumérez les valeurs qu'il contient:

Dictionary<int, string> dic;

foreach(string s in dic.Values)
{
   Console.WriteLine(s);
}

ou les KeyValuePairs

foreach(KeyValuePair<int, string> kvp in dic)
{
   Console.WriteLine("Key : " + kvp.Key.ToString() + ", Value : " + kvp.Value);
}

ou les clés

foreach(int key in dic.Keys)
{
    Console.WriteLine(key.ToString());
}

Si vous souhaitez mettre à jour les éléments du dictionnaire, vous devez le faire légèrement différemment, car vous ne pouvez pas mettre à jour l'instance lors de l'énumération. Ce que vous devrez faire est d'énumérer une collection différente qui n'est pas mise à jour, comme ceci:

Dictionary<int, string> newValues = new Dictionary<int, string>() { 1, "Test" };
foreach(KeyValuePair<int, string> kvp in newValues)
{
   dic[kvp.Key] = kvp.Value; // will automatically add the item if it's not there
}

Pour supprimer des éléments, procédez de la même manière, en énumérant la collection d'éléments que nous voulons supprimer plutôt que le dictionnaire lui-même.

List<int> keys = new List<int>() { 1, 3 };
foreach(int key in keys)
{
   dic.Remove(key);
}
81
Ian

En réponse au problème "Je ne peux pas mettre à jour la valeur/la clé dans foreach ()", vous ne pouvez pas modifier une collection lors de son énumération. J'aborderais cela en faisant une copie de la collection Keys:

Dictionary<int,int> dic=new Dictionary<int, int>();

//...fill the dictionary

int[] keys = dic.Keys.ToArray();
foreach (int i in keys)
{
    dic.Remove(i);
}
9
spender

Pour chaque. Il existe trois méthodes: Vous pouvez énumérer sur la propriété Keys, sur la propriété Values ou sur le dictionnaire lui-même qui est un énumérateur de KeyValuePair<TKey, TValue>.

8
Matthias Meid

Je viens de répondre à la même question (mise à jour) pour les listes, alors voici la même chose pour les dictionnaires.

public static void MutateEach(this IDictionary<TKey, TValue> dict, Func<TKey, TValue, KeyValuePair<TKey, TValue>> mutator)
{
    var removals = new List<TKey>();
    var additions = new List<KeyValuePair<TKey, TValue>>();

    foreach (var pair in dict)
    {
        var newPair = mutator(pair.Key, pair.Value);
        if ((newPair.Key != pair.Key) || (newPair.Value != pair.Value))
        {
            removals.Add(pair.Key);
            additions.Add(newPair);
        }
    }

    foreach (var removal in removals)
        dict.Remove(removal);

    foreach (var addition in additions)
        dict.Add(addition.Key, addition.Value);
}

Notez que nous devons faire les mises à jour en dehors de la boucle, donc nous ne modifions pas le dictionnaire au fur et à mesure que nous l'énumérons. De plus, cela détecte les conflits causés par la création de deux clés identiques - il lancera (en raison de l'utilisation de Add).

Exemple - mettez toutes les clés en minuscules et coupez toutes les valeurs, avec un Dictionary<string, string>:

myDict.MutateEach(key => key.ToLower(), value => value.Trim());

Si les clés ne sont pas uniques lorsqu'elles sont en minuscules, cela sera renvoyé.

2
Daniel Earwicker