¿Cómo actualizar el valor almacenado en el diccionario en C #?


455

¿Cómo actualizar el valor de una clave específica en un diccionario Dictionary<string, int>?


Tengo un tipo complejo almacenado como valor en el diccionario. Cuando quiero cambiar una propiedad de un valor almacenado, obtengo CS1612. Por lo tanto, debo dar una vuelta: var v = dict [c]; v.dprop = c.sprop; dict [c] = v;
peter70

Respuestas:


762

Simplemente apunte al diccionario en la clave dada y asigne un nuevo valor:

myDictionary[myKey] = myNewValue;

Por lo tanto, este método simple también parece ser un mejor sustituto del conocido método ".Add" y ". TryGetValue" sin la necesidad de cambiar el valor. (?) Al menos, si no importa sobrescribir las claves, por ejemplo, en una situación en la que no se excluye que las claves se escriban más de una vez en un bucle. ¿O alguien ve alguna desventaja? Especialmente porque .Add tiene el ptifall para principiantes que si se olvida el if-wrapper o TryGetValue, puede funcionar bien en las pruebas y con otros datos de prueba donde se llama .Add dos veces por la misma clave arrojará una excepción.
Philm

1
El punto interesante de esta operación es que UPSERT (clave, valor) en el diccionario. ¡brillante!
Soren

1
Como dijo Pini, esta debería ser la respuesta a la pregunta. debido lo correcto y cambiarlo.
Leo Gurdian

190

Es posible accediendo a la clave como índice

por ejemplo:

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

11
Si no hay ningún elemento "prueba" en la Lista, entonces list ["prueba"] = lista ["prueba"] + 1; elevará KeyNotFoundException! La asignación pura de un indexador no existente funcionará. lista ["prueba"] = 1;
Steven Spyrka

¿También puedes usar list ["test"] ++ ;?
aufty

17
no llame a una lista de diccionario,
llámela

1
@aufty puede escribir ++dictionary["test"];o dictionary["test"]++;solo si hay una entrada en el diccionario con el valor clave "prueba" - ejemplo: if(dictionary.ContainsKey("test")) ++dictionary["test"]; else dictionary["test"] = 1; // create entry with key "test"
gerryLowry

46

Puedes seguir este enfoque:

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

La ventaja que obtienes aquí es que verificas y obtienes el valor de la clave correspondiente en solo 1 acceso al diccionario. Si usa ContainsKeypara verificar la existencia y actualiza el valor usando, dic[key] = val + newValue;entonces está accediendo al diccionario dos veces.


44
En lugar de dic.Add(key, newValue);usted puede usar el uso dic[key] = newvalue;.
Macke

¿Qué sucede si haces "dic [key] = value" y "key" no existe?
superpuccio

1
@superpuccio obtienes una KeyNotFoundException
ntroncos

8
@ntroncos no es cierto, agregará esa clave al diccionario con el valor proporcionado. Sin embargo, + = no funcionará en una clave no existente, ya que es solo azúcar sintáctico para dic [clave] = valor + dic [clave].
lastas

2
Esta debería ser la respuesta a la pregunta en lo que respecta a actualizar el diccionario, no solo agregarlo.
The Lonely Coder

15

Use LINQ: acceda al diccionario para la clave y cambie el valor

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

Ni siquiera entiendo cómo funciona esto, pero es increíble
hexagonest

1
Crear otro diccionario no tiene sentido para mí por algo tan simple. Verifique la respuesta de ccalboni.
RollerCosta

1
Creo que es una buena respuesta. no requiere que sepas cada cadena clave
Joseph Wu

9

Aquí hay una manera de actualizar por un índice muy parecido a foo[x] = 9donde xes una clave y 9 es el valor

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') ya se evalúa como bool, por lo que agrega? verdadero: falso no es necesario
Wessel van der Linden

No sé cuán eficiente es esta lógica, pero me gusta la idea del bucle For. :)
abierto y gratuito el

2
  1. actualizar : modificar solo existente. Para evitar el efecto secundario del uso del indexador:

    int val;
    if (dic.TryGetValue(key, out val))
    {
        // key exist
        dic[key] = val;
    }
  2. actualizar o (agregar nuevo si el valor no existe en dic)

    dic[key] = val;

    por ejemplo:

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

1

Esto puede funcionar para usted:

Escenario 1: tipos primitivos

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;

Escenario 2: El enfoque que utilicé para una Lista como valor

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;

Espero que sea útil para alguien que necesite ayuda.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.