Làm cách nào để cập nhật giá trị được lưu trong Từ điển trong C #?


455

Làm cách nào để cập nhật giá trị cho một khóa cụ thể trong từ điển Dictionary<string, int>?


Tôi có một loại phức tạp được lưu trữ như giá trị trong từ điển. Khi tôi muốn thay đổi một thuộc tính có giá trị được lưu trữ, tôi nhận CS1612. Do đó tôi phải thực hiện một cách: var v = dict [c]; v.dprop = c.sprop; dict [c] = v;
peter70

Câu trả lời:


762

Chỉ cần trỏ đến từ điển tại khóa đã cho và gán một giá trị mới:

myDictionary[myKey] = myNewValue;

Vì vậy, phương pháp đơn giản này dường như cũng là một thay thế tốt hơn cho phương thức ".Add" và ".TryGetValue" nổi tiếng mà không cần thiết phải thay đổi giá trị. (?) Ít nhất, nếu việc ghi đè các khóa không thành vấn đề, ví dụ trong trường hợp không loại trừ, các khóa được ghi nhiều lần trong một vòng lặp. Hay ai đó thấy bất kỳ nhược điểm? Đặc biệt bởi vì .Add có ptifall cho người mới bắt đầu rằng nếu if-Wrapper hoặc TryGetValue bị quên, nó có thể hoạt động tốt trong các thử nghiệm và với dữ liệu thử nghiệm khác trong đó .Add được gọi hai lần cho cùng một khóa, nó sẽ ném ngoại lệ.
Philm

1
Điểm thú vị của thao tác này là, nó đưa UPSERT (khóa, giá trị) vào từ điển. xuất sắc!
Soren

1
Như Pini đã nêu, đây sẽ là câu trả lời cho câu hỏi. do điều đúng và thay đổi nó.
Leo Gurdian 17/03/2017

190

Có thể bằng cách truy cập khóa dưới dạng chỉ mục

ví dụ:

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

11
Nếu không có mục "kiểm tra" trong Danh sách, thì liệt kê ["kiểm tra"] = danh sách ["kiểm tra"] + 1; sẽ nâng KeyNotFoundException! Việc gán thuần túy của một bộ chỉ mục không tồn tại sẽ hoạt động. danh sách ["kiểm tra"] = 1;
Steven Spyrka

Bạn cũng có thể sử dụng danh sách ["test"] ++;?
bất ngờ

17
đừng gọi danh sách từ điển, gọi nó là chó hoặc mèo hoặc dict
user3800527 17/03/2016

1
@aufty bạn có thể viết ++dictionary["test"];hoặc dictionary["test"]++;nhưng chỉ khi có một mục trong từ điển với giá trị khóa "kiểm tra" - ví dụ: if(dictionary.ContainsKey("test")) ++dictionary["test"]; else dictionary["test"] = 1; // create entry with key "test"
gerryLowry

46

Bạn có thể làm theo phương pháp này:

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

Lợi thế bạn nhận được ở đây là bạn kiểm tra và nhận giá trị của khóa tương ứng chỉ trong 1 lần truy cập vào từ điển. Nếu bạn sử dụng ContainsKeyđể kiểm tra sự tồn tại và cập nhật giá trị sử dụng dic[key] = val + newValue;thì bạn đang truy cập từ điển hai lần.


4
Thay vì dic.Add(key, newValue);bạn có thể sử dụng sử dụng dic[key] = newvalue;.
Macke

Điều gì xảy ra nếu bạn không "dic [key] = value" và "key" không tồn tại?
superpuccio

1
@superpuccio bạn nhận được KeyNotFoundException
ntroncos

8
@ntroncos không đúng, nó sẽ thêm khóa đó vào từ điển với giá trị được cung cấp. + = sẽ không hoạt động trên một khóa không tồn tại, vì nó chỉ là đường cú pháp cho dic [key] = value + dic [key].
Lastas

2
Đây sẽ là câu trả lời cho câu hỏi vì nó liên quan đến việc cập nhật từ điển không chỉ thêm vào nó.
Bộ giải mã cô đơn

15

Sử dụng LINQ: Truy cập vào từ điển cho khóa và thay đổi giá trị

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

Tôi thậm chí không hiểu được cách thức hoạt động này, nhưng đó là tuyệt vời
hexagonest

1
Tạo một từ điển khác không có ý nghĩa với tôi cho điều đơn giản như vậy. Kiểm tra câu trả lời của ccalboni.
RollerCosta

1
Tôi nghĩ rằng đó là một câu trả lời tốt. nó không yêu cầu bạn phải biết từng chuỗi khóa
Joseph Wu

9

Đây là một cách để cập nhật bởi một chỉ số giống như foo[x] = 9nơi xlà một chìa khóa và 9 là giá trị

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') đã đánh giá thành một bool, vì vậy thêm? đúng: sai là không cần thiết
Tàu van der Linden

Tôi không biết logic này hiệu quả đến mức nào, nhưng tôi thích ý tưởng vòng lặp For. :)
mở và miễn phí

2
  1. cập nhật - chỉ sửa đổi tồn tại. Để tránh tác dụng phụ của việc sử dụng bộ chỉ mục:

    int val;
    if (dic.TryGetValue(key, out val))
    {
        // key exist
        dic[key] = val;
    }
  2. cập nhật hoặc (thêm mới nếu giá trị không tồn tại trong dic)

    dic[key] = val;

    ví dụ:

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

1

Điều này có thể làm việc cho bạn:

Kịch bản 1: kiểu nguyên thủy

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;

Kịch bản 2: Cách tiếp cận tôi sử dụng cho Danh sách làm Giá trị

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;

Hy vọng nó hữu ích cho người cần giúp đỡ.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.