Come aggiornare il valore memorizzato nel dizionario in C #?


455

Come aggiornare il valore per una chiave specifica in un dizionario Dictionary<string, int>?


Ho un tipo complesso memorizzato come valore nel dizionario. Quando voglio cambiare una proprietà di un valore memorizzato, ottengo CS1612. Quindi devo fare un giro: var v = dict [c]; v.dprop = c.sprop; dict [c] = v;
peter70,

Risposte:


762

Basta puntare al dizionario su una determinata chiave e assegnare un nuovo valore:

myDictionary[myKey] = myNewValue;

Quindi questo semplice metodo sembra essere anche un sostituto migliore per i noti metodi ".Add" e ". TryGetValue" senza la necessità di modificare il valore. (?) Almeno, se non importa sovrascrivere le chiavi, ad esempio in una situazione in cui non è escluso che le chiavi vengano scritte più di una volta in un ciclo. O qualcuno vede degli svantaggi? Soprattutto perché .Add ha il vantaggio per i principianti che se if-wrapper o TryGetValue viene dimenticato, può funzionare bene nei test e con altri dati di test in cui .Add viene chiamato due volte per la stessa chiave genererà un'eccezione.
Philm,

1
il punto interessante di questa operazione è che UPSERT (chiave, valore) nel dizionario. brillante!
Soren,

1
Come affermato da Pini, questa dovrebbe essere la risposta alla domanda. dovuto la cosa giusta e cambiarla.
Leo Gurdian,

190

È possibile accedendo alla chiave come indice

per esempio:

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

11
Se non esiste alcun elemento "test" nell'elenco, quindi list ["test"] = list ["test"] + 1; genererà KeyNotFoundException! La pura assegnazione di un indicizzatore inesistente funzionerà. list ["test"] = 1;
Steven Spyrka,

Puoi anche usare list ["test"] ++ ;?
aufty

17
non chiamare un elenco di dizionari, chiamalo cani o gatti o dict
user3800527

1
@aufty puoi scrivere ++dictionary["test"];o dictionary["test"]++;ma solo se c'è una voce nel dizionario con il valore chiave "test" - esempio: if(dictionary.ContainsKey("test")) ++dictionary["test"]; else dictionary["test"] = 1; // create entry with key "test"
gerryLowry

46

Puoi seguire questo approccio:

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

Il vantaggio che ottieni qui è che controlli e ottieni il valore della chiave corrispondente in 1 solo accesso al dizionario. Se si utilizza ContainsKeyper verificare l'esistenza e aggiornare il valore utilizzando, dic[key] = val + newValue;si accede al dizionario due volte.


4
Invece di dic.Add(key, newValue);te puoi usare use dic[key] = newvalue;.
Macke,

Cosa succede se si fa "dic [chiave] = valore" e "chiave" non esiste?
superpuccio,

1
@superpuccio ottieni KeyNotFoundException
ntroncos,

8
@ntroncos non è vero, aggiungerà quella chiave al dizionario con il valore fornito. + = non funzionerà su una chiave inesistente, poiché è solo zucchero sintattico per dic [chiave] = valore + dic [chiave].
dura il

2
Questa dovrebbe essere la risposta alla domanda per quanto riguarda l'aggiornamento del dizionario non solo l'aggiunta ad esso.
The Lonely Coder,

15

Usa LINQ: accedi al dizionario per la chiave e modifica il valore

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

Non capisco nemmeno come funzioni, ma è incredibile
esagonale

1
Creare un altro dizionario non ha senso per me per una cosa così semplice. Controlla la risposta di ccalboni.
RollerCosta

1
penso che sia una buona risposta. non richiede di conoscere ogni stringa di chiave
Joseph Wu,

9

Ecco un modo per aggiornare con un indice molto simile a foo[x] = 9dove xè una chiave e 9 è il valore

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
the m [i] .Equals ('1') ha già un valore bool, quindi aggiungendo? vero: falso non è necessario
Wessel van der Linden,

Non so quanto sia efficiente questa logica, ma mi piace l'idea del ciclo For. :)
aperto e gratuito il

2
  1. aggiornamento - modifica solo esistente. Per evitare effetti collaterali dell'uso dell'indicizzatore:

    int val;
    if (dic.TryGetValue(key, out val))
    {
        // key exist
        dic[key] = val;
    }
  2. aggiorna o (aggiungi nuovo se il valore non esiste in dic)

    dic[key] = val;

    per esempio:

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

1

Questo potrebbe funzionare per te:

Scenario 1: tipi primitivi

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;

Scenario 2: l'approccio che ho usato per un elenco come valore

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;

Spero sia utile per qualcuno che ha bisogno di aiuto.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.