C # Sözlük içinde depolanan değeri güncelleştirmek nasıl?


455

Sözlükteki belirli bir anahtarın değeri nasıl güncellenir Dictionary<string, int>?


Ben sözlükte değer olarak depolanan karmaşık bir türü var. Depolanmış bir değerin özelliğini değiştirmek istediğimde CS1612 alıyorum. Bu nedenle bir yol almalıyım: var v = dict [c]; v.dprop = c.sprop; dikte [c] = v;
peter70

Yanıtlar:


762

Sadece verilen anahtarda sözlüğe gidin ve yeni bir değer atayın:

myDictionary[myKey] = myNewValue;

Bu nedenle bu basit yöntem, değeri değiştirmeye gerek kalmadan, iyi bilinen ".Add" ve ".TryGetValue" yöntemi için daha iyi bir alternatif gibi görünmektedir. (?) En azından, anahtarların üzerine yazmanın önemi yoksa, örneğin anahtarların bir döngüde birden çok kez yazılmasının dışarıda bırakılmadığı bir durumda. Yoksa biri dezavantaj görüyor mu? Özellikle .Add yeni başlayanlar için ptifall'a sahip olduğundan, if-wrapper veya TryGetValue unutulursa, testlerde ve .Add'nin aynı anahtar için iki kez çağrıldığı diğer test verileriyle iyi çalışabileceği bir istisna atar.
Philm

1
Bu işlemin ilginç noktası, UPSERT (anahtar, değer) sözlüğüne girmesidir. parlak!
Soren

1
Pini'nin belirttiği gibi, sorunun cevabı bu olmalıdır. doğru olanı değiştirip değiştirin.
Leo Gurdian

190

Anahtara dizin olarak erişerek mümkündür

Örneğin:

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

11
Listede "test" öğesi yoksa, liste ["test"] = liste ["test"] + 1; KeyNotFoundException yükselecek! Mevcut olmayan bir dizinleyicinin saf ataması işe yarayacaktır. liste ["test"] = 1;
Steven Spyrka

List ["test"] ++ ;?
aufty

17
sözlük listesini arama, köpek ya da kedi ya da
dikte deme

1
@aufty yazabilirsiniz ++dictionary["test"];ya da dictionary["test"]++;ancak sözlükte "test" anahtar değerine sahip bir giriş varsa - örnek: if(dictionary.ContainsKey("test")) ++dictionary["test"]; else dictionary["test"] = 1; // create entry with key "test"
gerryLowry

46

Bu yaklaşımı takip edebilirsiniz:

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

Burada elde ettiğiniz kenar, sözlüğe sadece 1 erişimde karşılık gelen anahtarın değerini kontrol etmeniz ve almanızdır. Eğer kullanırsanız ContainsKeykullanarak değerini varlığını kontrol etmek ve güncellemek için dic[key] = val + newValue;iki kez sözlüğü erişen sonra.


4
Bunun yerine dic.Add(key, newValue);kullanımı kullanabilirsiniz dic[key] = newvalue;.
Macke

"Dic [key] = value" ve "key" mevcut değilse ne olur?
superpuccio

1
@superpuccio bir KeyNotFoundException
ntroncos

8
@ntroncos doğru değilse, söz konusu anahtarı söz konusu değere sağlanan değere ekler. + = mevcut olmayan bir anahtar üzerinde çalışmaz, çünkü dic [key] = value + dic [key] için sadece sözdizimsel şekerdir.
lastas

2
Bu, sadece sözlüğe eklenmekle kalmayan sözlüğü güncellemeye ilişkin sorunun cevabı olmalıdır.
Yalnız Kodlayıcı

15

LINQ kullanın: Anahtar için sözlüğe erişim ve değeri değiştirme

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

Bunun nasıl çalıştığını bile anlamıyorum ama inanılmaz
altıgen

1
Başka bir sözlük oluşturmak bu kadar basit bir şey için bana mantıklı gelmiyor. Kalbonboni'nin cevabını kontrol edin.
RollerCosta

1
bence bu iyi bir cevap. her bir anahtar dizeyi bilmenizi gerektirmez
Joseph Wu

9

Burada, bir anahtarın ve 9'un değerinin foo[x] = 9olduğu gibi bir dizine göre güncelleme yapmanın bir yolux

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') zaten bir boole olarak değerlendirilir, yani? true: yanlış gerekli değildir
Wessel van der Linden

Bu mantığın ne kadar verimli olduğunu bilmiyorum, ama For döngüsü fikrini seviyorum. :)
açık ve ücretsiz

2
  1. güncelleme - sadece var olanı değiştir. Dizin oluşturucu yan etkisinden kaçınmak için:

    int val;
    if (dic.TryGetValue(key, out val))
    {
        // key exist
        dic[key] = val;
    }
  2. güncelleyin veya ( dic'de değer yoksa yeni ekleyin )

    dic[key] = val;

    Örneğin:

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

1

Bu sizin için işe yarayabilir:

Senaryo 1: ilkel türler

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;

Senaryo 2: Liste Olarak Değer Olarak Kullandığım Yaklaşım

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;

Umarım yardıma muhtaç biri için faydalıdır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.