Como atualizar o valor armazenado no dicionário em c #?


455

Como atualizar o valor de uma chave específica em um dicionário Dictionary<string, int>?


Eu tenho um tipo complexo armazenado como valor no dicionário. Quando quero alterar uma propriedade de um valor armazenado, recebo CS1612. Portanto, devo dar uma volta: var v = dict [c]; v.dprop = c.sprop; ditado [c] = v;
Peter70

Respostas:


762

Basta apontar para o dicionário em uma determinada chave e atribuir um novo valor:

myDictionary[myKey] = myNewValue;

Portanto, esse método simples também parece ser um substituto melhor para o conhecido método ".Add" e ".TryGetValue" sem a necessidade de alterar o valor. (?) Pelo menos, se não importa sobrescrever chaves, por exemplo, em uma situação em que não seja excluído, as chaves são gravadas mais de uma vez em um loop. Ou alguém vê alguma desvantagem? Especialmente porque .Add possui o ptifall para iniciantes que, se o wrapper if ou TryGetValue for esquecido, ele poderá funcionar bem em testes e com outros dados de teste em que o .Add for chamado duas vezes para a mesma chave, gerará uma exceção.
Philm

1
o ponto interessante desta operação é que, INSERIR (chave, valor) no dicionário. brilhante!
Soren

1
Como Pini afirmou, esta deve ser a resposta para a pergunta. devido a coisa certa e alterá-lo.
Leo Gurdian

190

É possível acessando a chave como índice

por exemplo:

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

11
Se não houver nenhum item "teste" na Lista, lista ["teste"] = lista ["teste"] + 1; irá gerar KeyNotFoundException! A atribuição pura de um indexador inexistente funcionará. lista ["teste"] = 1;
Steven Spyrka

Você também pode usar a lista ["teste"] ++ ;?
aufty

17
não chame uma lista de dicionários, chame-a de cães, gatos ou dict #
user3800527 17/16/16

1
@aufty você pode escrever ++dictionary["test"];ou dictionary["test"]++;mas apenas se houver uma entrada no dicionário com o valor da chave "teste" - exemplo: if(dictionary.ContainsKey("test")) ++dictionary["test"]; else dictionary["test"] = 1; // create entry with key "test"
gerryLowry

46

Você pode seguir esta abordagem:

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

A vantagem que você obtém aqui é que você verifica e obtém o valor da chave correspondente em apenas 1 acesso ao dicionário. Se você ContainsKeyverificar a existência e atualizar o valor usando dic[key] = val + newValue;, estará acessando o dicionário duas vezes.


4
Em vez de dic.Add(key, newValue);você pode usar use dic[key] = newvalue;.
26615 Macke

O que acontece se você "dic [key] = value" e "key" não existirem?
Superpuccio

1
@superpuccio você começa um KeyNotFoundException
ntroncos

8
@ntroncos não é verdade, ele adicionará essa chave ao dicionário com o valor fornecido. + = não funcionará em uma chave inexistente, pois é apenas um açúcar sintático para dic [chave] = valor + dic [chave].
Lastas

2
Essa deve ser a resposta para a pergunta, no que se refere à atualização do dicionário e não apenas à adição dele.
The Lonely Coder

15

Use LINQ: acesso ao dicionário para a chave e altere o valor

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

Eu nem sequer entender como isso funciona, mas é incrível
hexagonest

1
Criar outro dicionário não faz sentido para mim por uma coisa tão simples. Verifique a resposta de ccalboni.
RollerCosta

1
Eu acho que é uma boa resposta. ele não exige que você saiba cada corda chave
Joseph Wu

9

Aqui está uma maneira de atualizar por um índice, bem como foo[x] = 9onde xestá uma chave e 9 é o 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
o m [i] .Equals ('1') já é avaliado como um bool, então adicionando? verdade: false não é necessário
Wessel van der Linden

Não sei o quão eficiente é essa lógica, mas gosto da ideia do loop For. :)
aberto e gratuito

2
  1. atualizar - modificar apenas existente. Para evitar o efeito colateral do uso do indexador:

    int val;
    if (dic.TryGetValue(key, out val))
    {
        // key exist
        dic[key] = val;
    }
  2. update ou (adicione novo se o valor não existir no dic)

    dic[key] = val;

    por exemplo:

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

1

Isso pode funcionar para você:

Cenário 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;

Cenário 2: a abordagem que usei para uma 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 seja útil para alguém que precisa de ajuda.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.