Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/256.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将元素添加到列表字典中_C#_Dictionary - Fatal编程技术网

C# 将元素添加到列表字典中

C# 将元素添加到列表字典中,c#,dictionary,C#,Dictionary,我有 Dictionary myDict=newdictionary(); 在某些时候,我想为特定的字典键向myDict添加数字 我现在正在做 Dictionary<string, List<int>> myDict = new Dictionary<string, List<int>>(); if(!myDict.ContainsKey(newKey)){ myDict[newKey]=新列表(); } myDict[newKey].Add(

我有

Dictionary myDict=newdictionary();
在某些时候,我想为特定的字典键向myDict添加数字

我现在正在做

Dictionary<string, List<int>> myDict = new Dictionary<string, List<int>>();
if(!myDict.ContainsKey(newKey)){
myDict[newKey]=新列表();
}
myDict[newKey].Add(myNumber);
但这似乎是一个容易在某个时候忘记ContainsKey检查的错误。 我已经找到了一种方法,可以让词典返回一个新列表,以防myDict[“entry”]还不存在,但我找不到任何内容。

您可以使用:


如果使用
ConcurrentDictionary
,可以执行以下操作:

Dictionary<string, List<int>> myDict = new Dictionary<string, List<int>>();

public void AddNumber(string key, int value)
{
     List<int> list;
     if(!myDict.TryGetValue(key, out list))
     {
         list = new List<int>();
         myDict.Add(key, list);
     }
     list.Add(value);
}
myDict.GetOrAdd(newKey,newlist()).Add(myNumber);

您可以实际使用其他人的建议。通过将访问封装在方法中,甚至使用ConcurrentDictionary

但对我来说,我会有一个自定义词典,这样你就可以真正实现
myDict[“entry”]
在没有看到元素时所做的事情

这样做的好处是,您可以完全控制您希望这本词典的行为方式

类MyCustomDictionary:IDictionary
其中TValue:class,new()
{
私人词典;
公共MyCustomDictionary()
{
_字典=新字典();
}
public TValue this[TKey]//这才是最重要的
{
得到
{
TValue-val;
if(!\u dictionary.TryGetValue(key,out val))//如果该键没有元素,则添加新元素并返回它
{
_Add(key,newtValue());
返回字典[键];
}
else//else返回找到的元素
{
返回val;
}
}
设置
{
_字典[键]=值;
}
}
公共无效添加(TKey键,TValue值)
{
_添加(键、值);
}
公共bool ContainsKey(TKey)
{
返回_dictionary.ContainsKey(key);
}
公共ICollection密钥
{
获取{return\u dictionary.Keys;}
}
公用门移除(TKey)
{
返回_dictionary.Remove(键);
}
公共bool TryGetValue(TKey键,out TValue值)
{
返回_dictionary.TryGetValue(键,输出值);
}
公共ICollection值
{
获取{return\u dictionary.Values;}
}
公共作废添加(KeyValuePair项)
{
_dictionary.Add(item.Key、item.Value);
}
公共空间清除()
{
_dictionary.Clear();
}
public bool包含(KeyValuePair项)
{
返回_dictionary.Contains(项);
}
public void CopyTo(KeyValuePair[]数组,int-arrayIndex)
{
_dictionary.ToList().CopyTo(array,arrayIndex);//您需要这个吗?您可以留下这个:)
}
公共整数计数
{
获取{return\u dictionary.Count;}
}
公共图书馆是只读的
{
获取{return false;}
}
公共布尔删除(KeyValuePair项)
{
return _dictionary.Remove(item.Key);
}
公共IEnumerator GetEnumerator()
{
返回_dictionary.GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
返回_dictionary.GetEnumerator();
}
}
然后你可以像这样使用它:

class MyCustomDictionary<TKey, TValue> : IDictionary<TKey, TValue>
    where TValue : class, new()
{
    private Dictionary<TKey, TValue> _dictionary;

    public MyCustomDictionary()
    {
        _dictionary = new Dictionary<TKey, TValue>();
    }

    public TValue this[TKey key] // this is what's important
    {
        get
        {
            TValue val;
            if (!_dictionary.TryGetValue(key, out val)) // if there is no element for that key, add a new element and return it
            {
                _dictionary.Add(key, new TValue());
                return _dictionary[key];
            }
            else // else return the found element
            {
                return val;
            }
        }
        set
        {
            _dictionary[key] = value;
        }
    }

    public void Add(TKey key, TValue value)
    {
        _dictionary.Add(key, value);
    }

    public bool ContainsKey(TKey key)
    {
        return _dictionary.ContainsKey(key);
    }

    public ICollection<TKey> Keys
    {
        get { return _dictionary.Keys; }
    }

    public bool Remove(TKey key)
    {
        return _dictionary.Remove(key);
    }

    public bool TryGetValue(TKey key, out TValue value)
    {
        return _dictionary.TryGetValue(key, out value);
    }

    public ICollection<TValue> Values
    {
        get { return _dictionary.Values; }
    }

    public void Add(KeyValuePair<TKey, TValue> item)
    {
        _dictionary.Add(item.Key, item.Value);
    }

    public void Clear()
    {
        _dictionary.Clear();
    }

    public bool Contains(KeyValuePair<TKey, TValue> item)
    {
        return _dictionary.Contains(item);
    }

    public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
    {
        _dictionary.ToList().CopyTo(array, arrayIndex); // do you need this? you can leave this :)
    }

    public int Count
    {
        get { return _dictionary.Count; }
    }

    public bool IsReadOnly
    {
        get { return false; }
    }

    public bool Remove(KeyValuePair<TKey, TValue> item)
    {
        return _dictionary.Remove(item.Key);
    }

    public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
    {
        return _dictionary.GetEnumerator();
    }

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        return _dictionary.GetEnumerator();
    }
}
MyCustomDictionary myCustomDict=新建MyCustomDictionary();
//返回一个int的新列表
var someelement that notfound=myCustomDict[“keythaisnotexistent”];

您可以使用
TryGetValue
方法:如果字典中有键 您只需将值添加到列表中;否则你应该 添加具有以下值的列表:

MyCustomDictionary<string, List<int>> myCustomDict = new MyCustomDictionary<int, List<int>>();
// return a new List of int
var someElementThatIsNotFound = myCustomDict["keyThatIsNonExistent"];
列表
if(myDict.TryGetValue(newKey,out list))
列表。添加(myNumber);
其他的
Add(newKey,newlist(){myNumber});

下面是我提到的
LazyLookup
示例的一个相对简单的实现。出于回答问题的简洁性,它只实现了
IEnumerable

本质上,在访问索引时,它将确保它已经初始化为
列表
类的新实例

List<int> list

if (myDict.TryGetValue(newKey, out list))
  list.Add(myNumber);
else
  myDict.Add(newKey, new List<int>() { myNumber });
公共类LazyLookup:IEnumerable
{
私人只读词典;
私有只读Func LazyListCreator;
公共懒散查找()
:此(()=>新列表())
{
}
公共懒散查找(Func lazyListCreator)
{
this.LazyListCreator=LazyListCreator;
this.CachedEntries=新字典();
}
公共列表此[TKey]
{
得到
{
返回GetOrCreateValue(键);
}
}
私有列表GetOrCreateValue(TKey)
{
列出返回值;
if(!CachedEntries.TryGetValue(key,out returnValue))
{
returnValue=LazyListCreator();
CachedEntries[键]=返回值;
}
返回值;
}
公共IEnumerator GetEnumerator()
{
返回CachedEntries.Values.GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
返回GetEnumerator();
}
}
有一些用法:

public class LazyLookup<TKey, TValue> : IEnumerable<List<TValue>>
{
   private readonly Dictionary<TKey, List<TValue>> CachedEntries;
   private readonly Func<List<TValue>> LazyListCreator;

    public LazyLookup()
        : this(() => new List<TValue>())
    {

    }
    public LazyLookup(Func<List<TValue>> lazyListCreator)
    {
        this.LazyListCreator = lazyListCreator;
        this.CachedEntries = new Dictionary<TKey, List<TValue>>();
    }

    public List<TValue> this[TKey key]
    {
        get
        {
            return GetOrCreateValue(key);
        }
    }

    private List<TValue> GetOrCreateValue(TKey key)
    {
        List<TValue> returnValue;
        if (!CachedEntries.TryGetValue(key, out returnValue))
        {
            returnValue = LazyListCreator();
            CachedEntries[key] = returnValue;
        }
        return returnValue;
    }

    public IEnumerator<List<TValue>> GetEnumerator()
    {
        return CachedEntries.Values.GetEnumerator();
    }

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
}
var lazyLookup=new lazyLookup();
lazyLookup[“nocheck”]。添加(9001);
//产出9001
Console.WriteLine(lazyLookup[“nocheck”][0]);
//输出0,因为它是一个新初始化的列表
Console.WriteLine(lazyLookup[“someOtherLookup”].Count);

此时,您可以将其更新为线程安全(因为
GetOrCreateValue
当前不是线程安全的),或者对其进行泛化,使其不再假定为
List
而是任何类型,或者对其进行扩展以实现完整的
IDictionary
接口。但至少,如果你经常使用上面提到的模式,你可以考虑使用一些封装来简化字典的使用,这些封装使你的任务变得琐碎,并且消除了代码重复。我恳求
MyCustomDictionary<string, List<int>> myCustomDict = new MyCustomDictionary<int, List<int>>();
// return a new List of int
var someElementThatIsNotFound = myCustomDict["keyThatIsNonExistent"];
List<int> list

if (myDict.TryGetValue(newKey, out list))
  list.Add(myNumber);
else
  myDict.Add(newKey, new List<int>() { myNumber });
public class LazyLookup<TKey, TValue> : IEnumerable<List<TValue>>
{
   private readonly Dictionary<TKey, List<TValue>> CachedEntries;
   private readonly Func<List<TValue>> LazyListCreator;

    public LazyLookup()
        : this(() => new List<TValue>())
    {

    }
    public LazyLookup(Func<List<TValue>> lazyListCreator)
    {
        this.LazyListCreator = lazyListCreator;
        this.CachedEntries = new Dictionary<TKey, List<TValue>>();
    }

    public List<TValue> this[TKey key]
    {
        get
        {
            return GetOrCreateValue(key);
        }
    }

    private List<TValue> GetOrCreateValue(TKey key)
    {
        List<TValue> returnValue;
        if (!CachedEntries.TryGetValue(key, out returnValue))
        {
            returnValue = LazyListCreator();
            CachedEntries[key] = returnValue;
        }
        return returnValue;
    }

    public IEnumerator<List<TValue>> GetEnumerator()
    {
        return CachedEntries.Values.GetEnumerator();
    }

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
}
var lazyLookup = new LazyLookup<string, int>();

lazyLookup["nocheck"].Add(9001);

//outputs 9001
Console.WriteLine(lazyLookup["nocheck"][0]);

//outputs 0 as it's a newly initialized list
Console.WriteLine(lazyLookup["someOtherLookup"].Count); 
    public static TVALUE GetOrSet<TKEY, TVALUE>(this IDictionary<TKEY, TVALUE> self,
                                                TKEY key,
                                                Func<TVALUE> defaultValue)
    {
        TVALUE value;
        if (!self.TryGetValue(key, out value))
        {
            value = defaultValue();
            self[key] = value;
        }
        return value;
    }   // eo GetOrSet
var dict = new Dictionary<string, List<int>>();

List<int> ints = dict.GetOrSet("list1", () => return new List<int>());
ints.Add(1);
dict.GetOrSet("list1", () => return new List<int>()).Add(1);