2010-04-12 63 views
31

我生病做的代碼塊像這樣不同的代碼位,我有:.NET字典和查找添加/更新

if (dict.ContainsKey[key]) { 
    dict[key] = value; 
} 
else { 
    dict.Add(key,value); 
} 

和查找(即鍵 - >的值列表)

if (lookup.ContainsKey[key]) { 
    lookup[key].Add(value); 
} 
else { 
    lookup.Add(new List<valuetype>); 
    lookup[key].Add(value); 
} 

是否有另一個集合lib或擴展方法,我應該用它在一行代碼中執行此操作,而不管鍵和值類型是什麼?

例如

dict.AddOrUpdate(key,value) 
lookup.AddOrUpdate(key,value) 
+0

是'lookup'是'ILookup '?我想不是因爲它不應該有一個'ContainsKey'方法。只是確認.NET沒有改變查詢的問題,因爲正在尋找一種方法來更新'ILookup' ... – drzaus 2015-05-30 09:44:52

回答

32

隨着葉夫根尼說,索引器將已經取代現有的價值觀 - 如果你只是要無條件地設置爲給定鍵的值,你可以做

dictionary[key] = value; 

更有趣的情況是「獲得價值,或者在必要時插入它」。這很容易與擴展方法做:

public static TValue GetOrCreateValue<TKey, TValue> 
    (this IDictionary<TKey, TValue> dictionary, 
    TKey key, 
    TValue value) 
{ 
    return dictionary.GetOrCreateValue(key,() => value); 
} 

public static TValue GetOrCreateValue<TKey, TValue> 
    (this IDictionary<TKey, TValue> dictionary, 
    TKey key, 
    Func<TValue> valueProvider) 
{ 
    TValue ret; 
    if (!dictionary.TryGetValue(key, out ret)) 
    { 
     ret = valueProvider(); 
     dictionary[key] = ret; 
    } 
    return ret; 
} 

的使用注意事項的委託來創建默認值 - 有利於像「列表,值」一個場景;你不希望創建一個空列表,除非你有:

dict.GetOrCreateValue(key,() => new List<int>()).Add(item); 

同樣要注意這僅執行查找一次如果鍵已經存在 - 有沒有必要做一個ContainsKey然後看提高價值。當它創建新值時仍然需要兩次查找。

1

林不知道是否有方法就像你問,但你可以寫一個小功能,或者使用try catch異常,想必如果你嘗試添加已經存在,它會拋出一個值一個例外。如果你理解並忽略它......只是一個建議

4

.NET 4.0中的ConcurrentDictionary有this nice method。你也可以爲此寫一個擴展方法。

14

更新時不需要執行檢查。簡單使用:

dict[key] = value 

它會替換任何現有的值。當不幸地檢索值時,沒有方便的單一方法(如Python中的setdefault),但您可以創建自己的擴展方法。事情是這樣的:

if (!lookup.TryGetValue(key, out value)) 
{ 
    value = new List<T>(); 
    lookup.Add(key, value); 
} 
3

如果使用.NET框架4或更高版本時,您可以使用AddOrUpdate Method

dict.AddOrUpdate(key,value) 

添加或更新是這樣

dict[key] = value; 
+4

這隻適用於'ConcurrentDictionary' – Mrchief 2014-09-30 18:04:12

+0

是的,你用它與Concurrent Dictionary,因爲你不'不想陷入陷阱中,檢查添加條件,確定你需要添加,然後讓其他東西添加在你的背後。 AddOrUpdate使它成爲原子,我相信。 – quillbreaker 2015-05-14 14:27:18

0

我喜歡法ConcurrentDictionaryAddOrUpdate,但我喜歡錶現字典集合太:)所以,這是所有類實現IDictionary的擴展方法。

public static TValue AddOrUpdate<TKey, TValue>(
    this IDictionary<TKey, TValue> dict, 
    TKey key, 
    TValue addValue, 
    Func<TKey, TValue, TValue> updateValueFactory) 
{ 
    TValue existing; 
    if (dict.TryGetValue(key, out existing)) 
    { 
     addValue = updateValueFactory(key, existing); 
     dict[key] = addValue; 
    } 
    else 
    { 
     dict.Add(key, addValue); 
    } 

    return addValue; 
} 


public static TValue AddOrUpdate<TKey, TValue>(
    this IDictionary<TKey, TValue> dict, 
    TKey key, 
    Func<TKey, TValue> addValueFactory, 
    Func<TKey, TValue, TValue> updateValueFactory) 
{ 
    TValue existing; 
    if (dict.TryGetValue(key, out existing)) 
    { 
     existing = updateValueFactory(key, existing); 
     dict[key] = existing; 
    } 
    else 
    { 
     existing = addValueFactory(key); 
     dict.Add(key, existing); 
    } 

    return existing; 
}