จะอัพเดทค่าที่เก็บไว้ใน Dictionary ใน C # ได้อย่างไร?


455

จะอัปเดตค่าสำหรับคีย์เฉพาะในพจนานุกรมได้Dictionary<string, int>อย่างไร


ฉันมีประเภทที่ซับซ้อนเก็บไว้เป็นค่าในพจนานุกรม เมื่อฉันต้องการเปลี่ยนคุณสมบัติของค่าที่เก็บไว้ฉันได้รับ CS1612 ดังนั้นฉันต้องหลีกทาง: var v = dict [c]; v.dprop = c.sprop; dict [c] = v;
peter70

คำตอบ:


762

เพียงชี้ไปที่พจนานุกรมที่คีย์ที่กำหนดและกำหนดค่าใหม่:

myDictionary[myKey] = myNewValue;

ดังนั้นวิธีการง่ายๆนี้ดูเหมือนจะเป็นการทดแทนที่ดีกว่าสำหรับวิธี ".Add" และ ".TryGetValue" ที่รู้จักกันดีโดยไม่จำเป็นต้องเปลี่ยนค่า (?) อย่างน้อยถ้ามันไม่สำคัญที่จะเขียนทับคีย์เช่นในสถานการณ์ที่ไม่ได้ยกเว้นว่ามีการเขียนคีย์มากกว่าหนึ่งครั้งในลูป หรือใครบางคนเห็นข้อเสียใด ๆ ? โดยเฉพาะอย่างยิ่งเนื่องจาก. เพิ่ม ptifall สำหรับผู้เริ่มต้นว่าหาก if-wrapper หรือ TryGetValue ถูกลืมมันสามารถทำงานได้ดีในการทดสอบและกับข้อมูลการทดสอบอื่น ๆ ที่. Add ถูกเรียกสองครั้งสำหรับคีย์เดียวกันมันจะทำให้เกิดข้อยกเว้น
Philm

1
จุดที่น่าสนใจของการดำเนินการนี้คือมันคือ UPSERT (คีย์, ค่า) ในพจนานุกรม ! สดใส
Soren

1
ตามที่ Pini ระบุไว้นี่ควรเป็นคำตอบของคำถาม เนื่องจากสิ่งที่ถูกต้องและเปลี่ยนแปลง
Leo Gurdian

190

เป็นไปได้ด้วยการเข้าถึงคีย์เป็นดัชนี

ตัวอย่างเช่น:

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

11
หากไม่มีรายการ "ทดสอบ" ในรายการให้ทำรายการ ["ทดสอบ"] = รายการ ["ทดสอบ"] + 1; จะเพิ่ม KeyNotFoundException! การกำหนดบริสุทธิ์ของตัวทำดัชนีที่ไม่มีอยู่จะทำงาน รายการ ["ทดสอบ"] = 1;
สตีเวน Spyrka

คุณสามารถใช้รายการ ["ทดสอบ"] ++;
aufty

17
อย่าเรียกรายชื่อพจนานุกรมเรียกมันว่าหมาหรือแมวหรือ dict
user3800527

1
@aufty คุณสามารถเขียน++dictionary["test"];หรือdictionary["test"]++;เฉพาะในกรณีที่มีรายการในพจนานุกรมที่มีค่าคีย์ "test" - ตัวอย่าง: if(dictionary.ContainsKey("test")) ++dictionary["test"]; else dictionary["test"] = 1; // create entry with key "test"
gerryLowry

46

คุณสามารถทำตามวิธีนี้:

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

ขอบที่คุณได้รับที่นี่คือคุณตรวจสอบและรับค่าของคีย์ที่เกี่ยวข้องในการเข้าถึงพจนานุกรมเพียง 1 ครั้ง หากคุณใช้ContainsKeyเพื่อตรวจสอบการมีอยู่และอัพเดตค่าโดยใช้dic[key] = val + newValue;คุณจะต้องเข้าสู่พจนานุกรมสองครั้ง


4
แทนการที่คุณสามารถใช้การใช้งานdic.Add(key, newValue); dic[key] = newvalue;
Macke

จะเกิดอะไรขึ้นหากคุณไม่พบ "dic [key] = value" และ "key"
superpuccio

1
@superpuccio คุณได้รับ KeyNotFoundException
ntroncos

8
@ntroncos ไม่เป็นความจริงจะเพิ่มคีย์นั้นลงในพจนานุกรมด้วยค่าที่ให้ไว้ + = จะไม่ทำงานกับคีย์ที่ไม่มีอยู่แม้ว่าจะเป็นเพียงน้ำตาลประโยคสำหรับ dic [key] = value + dic [key]
lastas

2
นี่ควรเป็นคำตอบสำหรับคำถามที่เกี่ยวข้องกับการอัพเดตพจนานุกรมไม่ใช่แค่เพิ่มเข้าไป
Loner Coder

15

ใช้ LINQ: การเข้าถึงพจนานุกรมสำหรับคีย์และเปลี่ยนค่า

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

ฉันไม่เข้าใจว่ามันใช้งานได้อย่างไร แต่มันน่าทึ่งมาก
หกเหลี่ยม

1
การสร้างพจนานุกรมอื่นไม่สมเหตุสมผลสำหรับฉันสำหรับเรื่องง่าย ๆ เช่นนี้ ตรวจสอบคำตอบของ ccalboni
RollerCosta

1
ฉันคิดว่ามันเป็นคำตอบที่ดี ไม่ต้องการให้คุณรู้ว่าแต่ละสตริงสำคัญ
Joseph Wu

9

นี่คือวิธีอัปเดตโดยดัชนีfoo[x] = 9ซึ่งคล้ายxกับคีย์และ 9 คือค่า

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') ประเมินค่าบูลแล้วเพิ่มหรือไม่ จริง: ไม่จำเป็นต้องมีเท็จ
Wessel van der Linden

ฉันไม่รู้ว่าตรรกะนี้มีประสิทธิภาพเพียงใด แต่ฉันชอบแนวคิด For For :)
เปิดและฟรี

2
  1. update - แก้ไขที่มีอยู่เท่านั้น วิธีหลีกเลี่ยงผลข้างเคียงจากการใช้ตัวทำดัชนี:

    int val;
    if (dic.TryGetValue(key, out val))
    {
        // key exist
        dic[key] = val;
    }
  2. อัปเดตหรือ (เพิ่มใหม่หากไม่มีค่าใน dic)

    dic[key] = val;

    เช่น:

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

1

สิ่งนี้อาจใช้ได้กับคุณ:

สถานการณ์ที่ 1: ชนิดดั้งเดิม

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;

สถานการณ์ที่ 2: วิธีการที่ฉันใช้สำหรับรายการเป็นค่า

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;

หวังว่ามันจะมีประโยชน์สำหรับใครบางคนที่ต้องการความช่วยเหลือ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.