Wie aktualisiere ich den im Wörterbuch in C # gespeicherten Wert?


455

Wie aktualisiere ich den Wert für einen bestimmten Schlüssel in einem Wörterbuch Dictionary<string, int>?


Ich habe einen komplexen Typ als Wert im Wörterbuch gespeichert. Wenn ich eine Eigenschaft eines gespeicherten Werts ändern möchte, erhalte ich CS1612. Deshalb muss ich einen Weg gehen: var v = dict [c]; v.dprop = c.sprop; diktiere [c] = v;
Peter70

Antworten:


762

Zeigen Sie einfach auf das Wörterbuch bei der angegebenen Taste und weisen Sie einen neuen Wert zu:

myDictionary[myKey] = myNewValue;

Daher scheint diese einfache Methode auch ein besserer Ersatz für die bekannten Methoden ".Add" und ".TryGetValue" zu sein, ohne dass der Wert geändert werden muss. (?) Zumindest, wenn es nicht wichtig ist, Schlüssel zu überschreiben, beispielsweise in einer Situation, in der nicht ausgeschlossen ist, dass Schlüssel mehr als einmal in einer Schleife geschrieben werden. Oder sieht jemand irgendwelche Nachteile? Insbesondere, weil .Add für Anfänger das Problem hat, dass wenn der if-Wrapper oder TryGetValue vergessen wird, er in Tests gut funktioniert und bei anderen Testdaten, bei denen .Add zweimal für denselben Schlüssel aufgerufen wird, eine Ausnahme ausgelöst wird.
Philm

1
Der interessante Punkt dieser Operation ist, dass UPSERT (Schlüssel, Wert) in das Wörterbuch aufgenommen wird. brillant!
Soren

1
Wie Pini sagte, sollte dies die Antwort auf die Frage sein. wegen der richtigen Sache und ändern Sie es.
Leo Gurdian

190

Dies ist möglich, indem Sie auf den Schlüssel als Index zugreifen

zum Beispiel:

Dictionary<string, int> dictionary = new Dictionary<string, int>();
dictionary["test"] = 1;
dictionary["test"] += 1;
Console.WriteLine (dictionary["test"]); // will print 2

11
Wenn die Liste kein Element "test" enthält, wird list ["test"] = list ["test"] + 1; wird KeyNotFoundException auslösen! Die reine Zuordnung eines nicht vorhandenen Indexers funktioniert. list ["test"] = 1;
Steven Spyrka

Können Sie auch list ["test"] ++; verwenden?
aufty

17
Nennen Sie keine Wörterbuchliste, nennen Sie es Hunde oder Katzen oder
diktieren Sie

1
@aufty können Sie schreiben ++dictionary["test"];oder dictionary["test"]++;aber nur, wenn es einen Eintrag im Wörterbuch mit dem Schlüsselwert "test" gibt - Beispiel: if(dictionary.ContainsKey("test")) ++dictionary["test"]; else dictionary["test"] = 1; // create entry with key "test"
gerryLowry

46

Sie können diesem Ansatz folgen:

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);
    }
}

Der Vorteil, den Sie hier erhalten, besteht darin, dass Sie den Wert des entsprechenden Schlüssels in nur einem Zugriff auf das Wörterbuch überprüfen und abrufen. Wenn Sie ContainsKeydie Existenz überprüfen und den Wert mit aktualisieren, greifen dic[key] = val + newValue;Sie zweimal auf das Wörterbuch zu.


4
Anstelle von können dic.Add(key, newValue);Sie verwenden dic[key] = newvalue;.
Macke

Was passiert, wenn Sie "dic [key] = value" ausführen und "key" nicht existiert?
Superpuccio

1
@ Superpuccio Sie erhalten eine KeyNotFoundException
ntroncos

8
@ntroncos nicht wahr, es wird dieser Schlüssel mit dem angegebenen Wert zum Wörterbuch hinzugefügt. + = funktioniert jedoch nicht mit einem nicht vorhandenen Schlüssel, da es sich nur um syntaktischen Zucker für dic [Schlüssel] = Wert + dic [Schlüssel] handelt.
Lastas

2
Dies sollte die Antwort auf die Frage sein, wenn es darum geht, das Wörterbuch zu aktualisieren und nicht nur zu ergänzen.
The Lonely Coder

15

Verwenden Sie LINQ: Zugriff auf das Wörterbuch für den Schlüssel und ändern Sie den Wert

Dictionary<string, int> dict = new Dictionary<string, int>();
dict = dict.ToDictionary(kvp => kvp.Key, kvp => kvp.Value + 1);

Ich verstehe nicht einmal, wie das funktioniert, aber es ist erstaunlich
sechseckigste

1
Das Erstellen eines anderen Wörterbuchs macht für mich für so eine einfache Sache keinen Sinn. Überprüfen Sie die Antwort von ccalboni.
RollerCosta

1
Ich denke, es ist eine gute Antwort. Es erfordert nicht, dass Sie jede Tastenfolge kennen
Joseph Wu

9

Hier ist eine Möglichkeit, durch einen Index zu aktualisieren, ähnlich wie foo[x] = 9bei xeinem Schlüssel und 9 als Wert

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;
    }
}

13
Die m [i] .Equals ('1') werden bereits zu einem Bool ausgewertet. wahr: falsch ist nicht notwendig
Wessel van der Linden

Ich weiß nicht, wie effizient diese Logik ist, aber ich mag die For-Loop-Idee. :)
geöffnet und kostenlos

2
  1. update - nur existent ändern. Um Nebenwirkungen des Indexers zu vermeiden, verwenden Sie:

    int val;
    if (dic.TryGetValue(key, out val))
    {
        // key exist
        dic[key] = val;
    }
    
  2. aktualisieren oder (neu hinzufügen, wenn der Wert in dic nicht vorhanden ist)

    dic[key] = val;

    zum Beispiel:

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

1

Dies kann für Sie funktionieren:

Szenario 1: Primitive Typen

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;

Szenario 2: Der Ansatz, den ich für eine Liste als Wert verwendet habe

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;

Hoffe, es ist nützlich für jemanden, der Hilfe braucht.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.