Bagaimana cara memperbarui nilai yang disimpan dalam Kamus di C #?


455

Bagaimana cara memperbarui nilai untuk kunci tertentu dalam kamus Dictionary<string, int>?


Saya memiliki tipe kompleks yang disimpan sebagai nilai dalam kamus. Ketika saya ingin mengubah properti dari nilai yang disimpan, saya mendapatkan CS1612. Karena itu saya harus mengambil jalan memutar: var v = dict [c]; v.dprop = c.sprop; dict [c] = v;
peter70

Jawaban:


762

Arahkan saja ke kamus di tombol yang diberikan dan berikan nilai baru:

myDictionary[myKey] = myNewValue;

Jadi metode sederhana ini tampaknya juga menjadi pengganti yang lebih baik untuk metode ".Add" dan ".TryGetValue" yang terkenal tanpa perlu mengubah nilainya. (?) Setidaknya, jika tidak masalah untuk menimpa kunci, misalnya dalam situasi di mana tidak dikecualikan bahwa kunci ditulis lebih dari satu kali dalam satu lingkaran. Atau apakah ada yang melihat kerugian? Terutama karena .Add memiliki ptifall untuk pemula bahwa jika if-wrapper atau TryGetValue dilupakan, ia dapat bekerja dengan baik dalam pengujian dan dengan data pengujian lainnya di mana .Add dipanggil dua kali untuk kunci yang sama, ia akan melempar pengecualian.
Philm

1
titik menarik dari operasi ini adalah bahwa, UPSERT (kunci, nilai) ke dalam kamus. cemerlang!
Soren

1
Seperti yang dikatakan Pini, ini harus menjadi jawaban untuk pertanyaan itu. karena hal yang benar dan mengubahnya.
Leo Gurdian

190

Itu mungkin dengan mengakses kunci sebagai indeks

sebagai contoh:

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

11
Jika tidak ada item "test" dalam Daftar, maka daftar ["test"] = daftar ["test"] +1; akan meningkatkan KeyNotFoundException! Penugasan murni dari pengindeks tidak ada akan bekerja. list ["test"] = 1;
Steven Spyrka

Bisakah Anda juga menggunakan daftar ["test"] ++ ;?
aufty

17
jangan panggil daftar kamus, sebut saja anjing atau kucing atau dict
user3800527

1
@aufty Anda dapat menulis ++dictionary["test"];atau dictionary["test"]++;tetapi hanya jika ada entri dalam kamus dengan nilai kunci "test" - contoh: if(dictionary.ContainsKey("test")) ++dictionary["test"]; else dictionary["test"] = 1; // create entry with key "test"
gerryLowry

46

Anda dapat mengikuti pendekatan ini:

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

Tepi yang Anda dapatkan di sini adalah bahwa Anda memeriksa dan mendapatkan nilai kunci yang sesuai hanya dalam 1 akses ke kamus. Jika Anda menggunakan ContainsKeyuntuk memeriksa keberadaan dan memperbarui nilai menggunakan dic[key] = val + newValue;maka Anda mengakses kamus dua kali.


4
Alih-alih dic.Add(key, newValue);Anda bisa menggunakan use dic[key] = newvalue;.
Macke

Apa yang terjadi jika Anda "dic [key] = value" dan "key" tidak ada?
superpuccio

1
@superpuccio Anda mendapatkan KeyNotFoundException
ntroncos

8
@ntroncos tidak benar, itu akan menambahkan kunci itu ke kamus dengan nilai yang diberikan. + = tidak akan bekerja pada kunci yang tidak ada, karena itu hanya gula sintaksis untuk dic [kunci] = nilai + dic [kunci].
berlangsung

2
Ini harus menjadi jawaban untuk pertanyaan sehubungan dengan memperbarui kamus tidak hanya menambahkannya.
The Lonely Coder

15

Gunakan LINQ: Akses ke kamus untuk kunci dan ubah nilainya

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

Saya bahkan tidak mengerti bagaimana ini bekerja tetapi itu luar biasa
hexagonest

1
Membuat kamus lain tidak masuk akal bagi saya untuk hal yang sederhana. Periksa jawaban ccalboni.
RollerCosta

1
Saya pikir itu adalah jawaban yang bagus. Anda tidak perlu mengetahui setiap string kunci
Joseph Wu

9

Berikut adalah cara untuk memperbarui dengan indeks seperti di foo[x] = 9mana xkuncinya dan 9 adalah nilainya

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]. Setara ('1') sudah dievaluasi menjadi bool, jadi menambahkan? true: false tidak perlu
Wessel van der Linden

Saya tidak tahu seberapa efisien logika ini, tapi saya suka ide For loop. :)
buka dan gratis

2
  1. perbarui - ubah hanya ada. Untuk menghindari efek samping dari penggunaan pengindeks:

    int val;
    if (dic.TryGetValue(key, out val))
    {
        // key exist
        dic[key] = val;
    }
  2. perbarui atau (tambahkan baru jika nilai tidak ada dalam dic)

    dic[key] = val;

    contohnya:

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

1

Ini mungkin bekerja untuk Anda:

Skenario 1: tipe primitif

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;

Skenario 2: Pendekatan yang saya gunakan untuk Daftar sebagai Nilai

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;

Semoga bermanfaat bagi seseorang yang membutuhkan bantuan.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.