簡體   English   中英

在Dictionary中自動創建集合 <Key, Collection<Value> &gt;

[英]Automatically creating a collection in the Dictionary<Key, Collection<Value>>

很多時候我必須創建一個Dictionary<KeyType, List<ValueType>>

在我開始使用字典之前,我必須首先驗證是否已為該密鑰創建了List。

//Can i remove these two lines?
if(!dict.ContainsKey(key)) 
    dict[key]= new List<ValueType>;

//now use the key
dict[key].Add(value);

我知道它只有“2行”的代碼,但它讓我煩惱,我認為它可以刪除。

我可以在某種程度上擴展字典,但在我做之前,我想知道是否有人找到了一種聰明的方法來刪除上面的if語句。

基本上我想創建一個Dictionary<KeyType, Collection<ValueType>>並立即開始使用它,如dict[key].Add(value)

您可以創建類似Google Java Collection的Multimap ...或者您可以添加如下的擴展方法:

public static void AddValue<TKey, TValue>
    (this IDictionary<TKey, List<TValue>> dictionary, TKey key, TValue value)
{
    List<TValue> values;
    if (!dictionary.TryGetValue(key, out values))
    {
        values = new List<TValue>();
        dictionary.Add(key, values);
    }
    values.Add(value);
}

正如Bevan所說, Lookup也可以提供幫助 - 但是你只能使用ToLookup方法創建一個,之后你就無法修改它。 在許多情況下,這是一件非常好的事情,但是如果你需要一個可變的地圖,那么你就會得到類似上面的東西。

看一看在LookUp在.NET 3.5的LINQ介紹類-它可能是你要找的:一個Dictionary一樣的類,支持每個鍵多個項目。

也許唯一重要的缺點是你必須在一個批次中提供所有元素,因為LookUp是不可變的。

ConcurrentDictionary<T,K>.GetOrAdd方法非常有用。

private ConcurrentDictionary<string, ICollection<int>> _dictionary;

private static ICollection<int> CreateEmptyList(string dummyKey)
{
    return new List<int>();
}

private void AddValue(string key, int value)
{
    ICollection<int> values = _dictionary.GetOrAdd(key, CreateEmptyList);
    values.Add(value);
}

編輯:以下是如何將該功能實現為IDictionary<T,K> (C#3)的擴展方法的示例:

請注意, IDictionary<TKey, TValue>通常不是線程安全的,因此如果您希望使用此擴展方法保證線程安全,則必須像其他操作一樣手動實現它。

public static TValue GetOrAdd<TKey, TValue>(
    this IDictionary<TKey, TValue> dictionary,
    TKey key,
    Func<TKey, TValue> valueFactory)
{
    TValue value;
    if (!dictionary.TryGetValue(key, out value))
    {
        value = valueFactory(key);
        dictionary.Add(key, value);
    }

    return value;
}

要添加答案,您還可以添加一個更通用的擴展,它接受委托進行實例化:

public static TValue GetOrCreate<TKey, TValue>
    (this IDictionary<TKey, TValue> dict, 
          TKey key, 
          Func<TKey, TValue> getValue)
{
    TValue value;
    if (!dict.TryGetValue(key, out value))
    {
        dict.Add(key, getValue(key));
    }
    return value;
}

然后你可以提供你喜歡的任何實例化方法:

Dictionary<int, string> dict = new Dictionary<int, string>();
string result = dict.GetOrCreate(5, i => i.ToString());

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM