Comment mettre à jour la valeur stockée dans Dictionary en C #?

455

Comment mettre à jour la valeur d'une clé spécifique dans un dictionnaire Dictionary<string, int>?

Amit
la source
J'ai un type complexe stocké comme valeur dans le dictionnaire. Lorsque je souhaite modifier une propriété d'une valeur stockée, j'obtiens CS1612. Je dois donc contourner: var v = dict [c]; v.dprop = c.sprop; dict [c] = v;
peter70

Réponses:

762

Pointez simplement le dictionnaire sur la clé donnée et attribuez une nouvelle valeur:

myDictionary[myKey] = myNewValue;
ccalboni
la source
Cette méthode simple semble donc également être un meilleur substitut aux méthodes bien connues ".Add" et ".TryGetValue" sans qu'il soit nécessaire de modifier la valeur. (?) Au moins, si cela n'a pas d'importance d'écraser des clés, par exemple dans une situation où il n'est pas exclu que les clés soient écrites plus d'une fois dans une boucle. Ou quelqu'un voit-il des inconvénients? Surtout parce que .Add a le ptifall pour les débutants que si le if-wrapper ou TryGetValue est oublié, il peut fonctionner correctement dans les tests et avec d'autres données de test où .Add est appelé deux fois pour la même clé, il lèvera une exception.
Philm
1
le point intéressant de cette opération est que, il UPSERT (clé, valeur) dans le dictionnaire. brillant!
Soren
1
Comme l'a déclaré Pini, cela devrait être la réponse à la question. en raison de la bonne chose et le changer.
Leo Gurdian
190

C'est possible en accédant à la clé comme index

par exemple:

Dictionary<string, int> dictionary = new Dictionary<string, int>();
dictionary["test"] = 1;
dictionary["test"] += 1;
Console.WriteLine (dictionary["test"]); // will print 2
Amit
la source
11
S'il n'y a pas d'élément "test" dans la liste, alors list ["test"] = list ["test"] + 1; va lever KeyNotFoundException! L'affectation pure d'un indexeur non existant fonctionnera. list ["test"] = 1;
Steven Spyrka
Pouvez-vous également utiliser list ["test"] ++ ;?
2016
17
ne pas appeler une liste de dictionnaires, appeler chiens ou chats ou dict
user3800527
1
@aufty vous pouvez écrire ++dictionary["test"];ou dictionary["test"]++;mais seulement s'il y a une entrée dans le dictionnaire avec la valeur clé "test" - exemple: if(dictionary.ContainsKey("test")) ++dictionary["test"]; else dictionary["test"] = 1; // create entry with key "test"
gerryLowry
46

Vous pouvez suivre cette approche:

void addOrUpdate(Dictionary<int, int> dic, int key, int newValue)
{
    int val;
    if (dic.TryGetValue(key, out val))
    {
        // yay, value exists!
        dic[key] = val + newValue;
    }
    else
    {
        // darn, lets add the value
        dic.Add(key, newValue);
    }
}

L'avantage que vous obtenez ici est que vous vérifiez et obtenez la valeur de la clé correspondante en seulement 1 accès au dictionnaire. Si vous utilisez ContainsKeypour vérifier l'existence et mettre à jour la valeur à l'aide de, dic[key] = val + newValue;vous accédez au dictionnaire deux fois.

max_force
la source
4
Au lieu de dic.Add(key, newValue);vous pouvez utiliser use dic[key] = newvalue;.
Macke
Que se passe-t-il si vous faites "dic [key] = value" et "key" n'existe pas?
superpuccio
1
@superpuccio vous obtenez une exception KeyNotFoundException
ntroncos
8
@ntroncos pas vrai, il ajoutera cette clé au dictionnaire avec la valeur fournie. + = ne fonctionnera pas sur une clé non existante, car il s'agit simplement de sucre syntaxique pour dic [clé] = valeur + dic [clé].
lastas
2
Cela devrait être la réponse à la question en ce qui concerne la mise à jour du dictionnaire et non seulement son ajout.
The Lonely Coder
15

Utilisez LINQ: accès au dictionnaire pour la clé et modifiez la valeur

Dictionary<string, int> dict = new Dictionary<string, int>();
dict = dict.ToDictionary(kvp => kvp.Key, kvp => kvp.Value + 1);
INT_24h
la source
Je ne comprends même pas comment cela fonctionne, mais c'est incroyable
hexagone
1
Créer un autre dictionnaire n'a pas de sens pour moi pour une chose aussi simple. Vérifiez la réponse de ccalboni.
RollerCosta
1
je pense que c'est une bonne réponse. cela ne vous oblige pas à connaître chaque chaîne de clé
Joseph Wu
9

Voici un moyen de mettre à jour par un index un peu comme foo[x] = 9xest une clé et 9 est la valeur

var views = new Dictionary<string, bool>();

foreach (var g in grantMasks)
{
    string m = g.ToString();
    for (int i = 0; i <= m.Length; i++)
    {
        views[views.ElementAt(i).Key] = m[i].Equals('1') ? true : false;
    }
}
Matthieu
la source
13
le m [i] .Equals ('1') évalue déjà à un booléen, donc en ajoutant? vrai: faux n'est pas nécessaire
Wessel van der Linden
Je ne sais pas à quel point cette logique est efficace, mais j'aime l'idée de boucle For. :)
ouvert et gratuit
2
  1. mise à jour - modifie l'existant uniquement. Pour éviter les effets secondaires de l'utilisation de l'indexeur:

    int val;
    if (dic.TryGetValue(key, out val))
    {
        // key exist
        dic[key] = val;
    }
  2. mettre à jour ou (ajouter un nouveau si la valeur n'existe pas dans le dic)

    dic[key] = val;

    par exemple:

    d["Two"] = 2; // adds to dictionary because "two" not already present
    d["Two"] = 22; // updates dictionary because "two" is now present
Vlad Novakovsky
la source
1

Cela peut fonctionner pour vous:

Scénario 1: types primitifs

string keyToMatchInDict = "x";
int newValToAdd = 1;
Dictionary<string,int> dictToUpdate = new Dictionary<string,int>{"x",1};

if(!dictToUpdate.ContainsKey(keyToMatchInDict))
   dictToUpdate.Add(keyToMatchInDict ,newValToAdd );
else
   dictToUpdate[keyToMatchInDict] = newValToAdd; //or you can do operations such as ...dictToUpdate[keyToMatchInDict] += newValToAdd;

Scénario 2: l'approche que j'ai utilisée pour une liste en tant que valeur

int keyToMatch = 1;
AnyObject objInValueListToAdd = new AnyObject("something for the Ctor")
Dictionary<int,List<AnyObject> dictToUpdate = new Dictionary<int,List<AnyObject>(); //imagine this dict got initialized before with valid Keys and Values...

if(!dictToUpdate.ContainsKey(keyToMatch))
   dictToUpdate.Add(keyToMatch,new List<AnyObject>{objInValueListToAdd});
else
   dictToUpdate[keyToMatch] = objInValueListToAdd;

J'espère que c'est utile pour quelqu'un qui a besoin d'aide.

Monsieur Pitt
la source