Jak zaktualizować wartość przechowywaną w słowniku w C #?


455

Jak zaktualizować wartość określonego klucza w słowniku Dictionary<string, int>?


Mam złożony typ przechowywany jako wartość w słowniku. Kiedy chcę zmienić właściwość przechowywanej wartości, otrzymuję CS1612. Dlatego muszę się obejść: var v = dict [c]; v.dprop = c.sprop; dict [c] = v;
peter70

Odpowiedzi:


762

Wystarczy wskazać słownik na dany klucz i przypisać nową wartość:

myDictionary[myKey] = myNewValue;

Ta prosta metoda wydaje się więc lepiej zastępować dobrze znaną metodę „.Add” i „.TryGetValue” bez konieczności zmiany wartości. (?) Przynajmniej, jeśli nie ma znaczenia nadpisywanie kluczy, na przykład w sytuacji, gdy nie jest wykluczone, że klucze są zapisywane więcej niż raz w pętli. Czy ktoś widzi jakieś wady? Zwłaszcza, że ​​.Add ma ptifall dla początkujących, że jeśli zapomnisz o wrapperu lub TryGetValue, może on działać dobrze w testach, a przy innych danych testowych, w których .Add jest wywoływany dwukrotnie dla tego samego klucza, wygeneruje wyjątek.
Philm

1
ciekawym punktem tej operacji jest to, że UPSERT (klucz, wartość) do słownika. znakomity!
Soren

1
Jak stwierdził Pini, powinna to być odpowiedź na pytanie. z powodu właściwej rzeczy i zmień to.
Leo Gurdian,

190

Jest to możliwe, uzyskując dostęp do klucza jako indeksu

na przykład:

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

11
Jeśli na liście nie ma pozycji „test”, wówczas lista [„test”] = lista [„test”] + 1; podniesie wyjątek KeyNotFoundException! Działa czyste przypisanie nieistniejącego indeksatora. list [„test”] = 1;
Steven Spyrka

Czy możesz również użyć list [„test”] ++ ;?
aufty

17
nie dzwoń do słownika, nazywaj go psami lub kotami lub
dyktuj

1
@aufty można napisać ++dictionary["test"];lub dictionary["test"]++;ale tylko wtedy, gdy istnieje wpis w słowniku z wartości klucza „test” - przykład: if(dictionary.ContainsKey("test")) ++dictionary["test"]; else dictionary["test"] = 1; // create entry with key "test"
gerryLowry

46

Możesz zastosować to podejście:

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

Zaletą jest to, że sprawdzasz i uzyskujesz wartość odpowiedniego klucza w zaledwie 1 dostępie do słownika. Jeśli użyjesz, ContainsKeyaby sprawdzić istnienie i zaktualizować wartość za pomocą dic[key] = val + newValue;, uzyskujesz dwukrotnie dostęp do słownika.


4
Zamiast dic.Add(key, newValue);ciebie możesz użyć dic[key] = newvalue;.
Macke,

Co się stanie, jeśli wykonasz „dic [klucz] = wartość” i „klucz” nie istnieje?
superpuccio,

1
@ superpuccio otrzymujesz KeyNotFoundException
ntroncos

8
@ntroncos nieprawda, doda ten klucz do słownika z podaną wartością. + = nie będzie działał na nieistniejącym kluczu, ponieważ jest to po prostu cukier składniowy dla dic [klucz] = wartość + dic [klucz].
lastas

2
To powinna być odpowiedź na pytanie dotyczące aktualizacji słownika, a nie tylko jego dodawania.
The Lonely Coder,

15

Użyj LINQ: Dostęp do słownika dla klucza i zmień wartość

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

Nawet nie rozumiem, jak to działa, ale to niesamowite
heksagonest

1
Tworzenie kolejnego słownika nie ma dla mnie sensu dla tak prostej rzeczy. Sprawdź odpowiedź ccalboni.
RollerCosta

1
myślę, że to dobra odpowiedź. nie wymaga znajomości każdego klucza
Joseph Wu

9

Oto sposób aktualizacji według indeksu, podobnie jak foo[x] = 9gdzie xjest klucz, a 9 to wartość

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
m [i] .Equals ('1') już ocenia na bool, więc dodawanie? prawda: fałsz nie jest konieczny
Wessel van der Linden

Nie wiem, jak skuteczna jest ta logika, ale podoba mi się pomysł na pętlę For. :)
otwarte i darmowe

2
  1. aktualizacja - modyfikuj tylko istniejące. Aby uniknąć skutków ubocznych używania indeksatora:

    int val;
    if (dic.TryGetValue(key, out val))
    {
        // key exist
        dic[key] = val;
    }
  2. zaktualizuj lub (dodaj nowy, jeśli wartość nie istnieje w trybie dic)

    dic[key] = val;

    na przykład:

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

1

To może Ci pomóc:

Scenariusz 1: typy pierwotne

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;

Scenariusz 2: Podejście zastosowane w przypadku Listy jako wartości

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;

Mam nadzieję, że jest to przydatne dla kogoś, kto potrzebuje pomocy.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.