我创建了字典对象
Dictionary<string, List<string>> dictionary =
new Dictionary<string,List<string>>();
我想将字符串值添加到给定单个键的字符串列表中。
如果密钥尚不存在,那么我必须添加一个新密钥。 List<string>
未预定义,我的意思是我没有创建任何列表对象,然后提供给dictionary.Add("key",Listname)
。如何在dictionary.Add("key",Listname)
中动态创建此列表对象,然后将字符串添加到此列表中。如果我必须添加100个密钥,那么在执行dictionary.Add
指令之前我是否必须创建100个列表?我还必须对此列表的内容进行定义吗?
谢谢。
答案 0 :(得分:29)
更新:使用TryGetValue
检查是否存在,只有在您拥有列表的情况下才进行一次查找:
List<int> list;
if (!dictionary.TryGetValue("foo", out list))
{
list = new List<int>();
dictionary.Add("foo", list);
}
list.Add(2);
<小时/> 的原件:强> 检查是否存在并添加一次,然后键入字典以获取列表并正常添加到列表中:
var dictionary = new Dictionary<string, List<int>>();
if (!dictionary.ContainsKey("foo"))
dictionary.Add("foo", new List<int>());
dictionary["foo"].Add(42);
dictionary["foo"].AddRange(oneHundredInts);
或List<string>
与您的情况一样。
顺便说一句,如果您知道要将多少项添加到动态集合(例如List<T>
)中,请使用具有初始列表容量的构造函数:new List<int>(100);
。
这将获取满足指定容量 upfront 所需的内存,而不是每次开始填充时抓取小块。如果您知道有100个键,则可以对词典执行相同的操作。
答案 1 :(得分:8)
如果我理解你想要的东西:
dictionary.Add("key", new List<string>());
信......
dictionary["key"].Add("string to your list");
答案 2 :(得分:6)
Dictionary<string, List<string>> dictionary = new Dictionary<string,List<string>>();
foreach(string key in keys) {
if(!dictionary.ContainsKey(key)) {
//add
dictionary.Add(key, new List<string>());
}
dictionary[key].Add("theString");
}
如果密钥不存在,则添加新的List
(如果在内)。否则密钥存在,所以只需在该密钥下的List
添加一个新值。
答案 3 :(得分:3)
您可以使用我的多地图实现,它来自Dictionary<K, List<V>>
。它并不完美,但它做得很好。
/// <summary>
/// Represents a collection of keys and values.
/// Multiple values can have the same key.
/// </summary>
/// <typeparam name="TKey">Type of the keys.</typeparam>
/// <typeparam name="TValue">Type of the values.</typeparam>
public class MultiMap<TKey, TValue> : Dictionary<TKey, List<TValue>>
{
public MultiMap()
: base()
{
}
public MultiMap(int capacity)
: base(capacity)
{
}
/// <summary>
/// Adds an element with the specified key and value into the MultiMap.
/// </summary>
/// <param name="key">The key of the element to add.</param>
/// <param name="value">The value of the element to add.</param>
public void Add(TKey key, TValue value)
{
List<TValue> valueList;
if (TryGetValue(key, out valueList)) {
valueList.Add(value);
} else {
valueList = new List<TValue>();
valueList.Add(value);
Add(key, valueList);
}
}
/// <summary>
/// Removes first occurence of an element with a specified key and value.
/// </summary>
/// <param name="key">The key of the element to remove.</param>
/// <param name="value">The value of the element to remove.</param>
/// <returns>true if the an element is removed;
/// false if the key or the value were not found.</returns>
public bool Remove(TKey key, TValue value)
{
List<TValue> valueList;
if (TryGetValue(key, out valueList)) {
if (valueList.Remove(value)) {
if (valueList.Count == 0) {
Remove(key);
}
return true;
}
}
return false;
}
/// <summary>
/// Removes all occurences of elements with a specified key and value.
/// </summary>
/// <param name="key">The key of the elements to remove.</param>
/// <param name="value">The value of the elements to remove.</param>
/// <returns>Number of elements removed.</returns>
public int RemoveAll(TKey key, TValue value)
{
List<TValue> valueList;
int n = 0;
if (TryGetValue(key, out valueList)) {
while (valueList.Remove(value)) {
n++;
}
if (valueList.Count == 0) {
Remove(key);
}
}
return n;
}
/// <summary>
/// Gets the total number of values contained in the MultiMap.
/// </summary>
public int CountAll
{
get
{
int n = 0;
foreach (List<TValue> valueList in Values) {
n += valueList.Count;
}
return n;
}
}
/// <summary>
/// Determines whether the MultiMap contains an element with a specific
/// key / value pair.
/// </summary>
/// <param name="key">Key of the element to search for.</param>
/// <param name="value">Value of the element to search for.</param>
/// <returns>true if the element was found; otherwise false.</returns>
public bool Contains(TKey key, TValue value)
{
List<TValue> valueList;
if (TryGetValue(key, out valueList)) {
return valueList.Contains(value);
}
return false;
}
/// <summary>
/// Determines whether the MultiMap contains an element with a specific value.
/// </summary>
/// <param name="value">Value of the element to search for.</param>
/// <returns>true if the element was found; otherwise false.</returns>
public bool Contains(TValue value)
{
foreach (List<TValue> valueList in Values) {
if (valueList.Contains(value)) {
return true;
}
}
return false;
}
}
请注意,Add
方法查看密钥是否已存在。如果密钥是新的,则创建新列表,将值添加到列表中,并将列表添加到字典中。如果密钥已存在,则新值将添加到现有列表中。
答案 4 :(得分:2)
虽然与大多数其他回复几乎相同,但我认为这是实现它的最有效和最简洁的方法。使用TryGetValue比使用ContainsKey并重新索引到字典中更快,正如其他一些解决方案所示。
void Add(string key, string val)
{
List<string> list;
if (!dictionary.TryGetValue(someKey, out list))
{
values = new List<string>();
dictionary.Add(key, list);
}
list.Add(val);
}
答案 5 :(得分:2)
使用NameValueCollection。
良好的起点是here。直接从链接。
System.Collections.Specialized.NameValueCollection myCollection
= new System.Collections.Specialized.NameValueCollection();
myCollection.Add(“Arcane”, “http://arcanecode.com”);
myCollection.Add(“PWOP”, “http://dotnetrocks.com”);
myCollection.Add(“PWOP”, “http://dnrtv.com”);
myCollection.Add(“PWOP”, “http://www.hanselminutes.com”);
myCollection.Add(“TWIT”, “http://www.twit.tv”);
myCollection.Add(“TWIT”, “http://www.twit.tv/SN”);
答案 6 :(得分:0)
添加字符串时,请根据密钥是否已存在而采用不同的方式。为密钥value
添加字符串key
:
List<string> list;
if (dictionary.ContainsKey(key)) {
list = dictionary[key];
} else {
list = new List<string>();
dictionary.Add(ley, list);
}
list.Add(value);
答案 7 :(得分:0)
为什么不转换为ILookup而不是使用Dictionary?
var myData = new[]{new {a=1,b="frog"}, new {a=1,b="cat"}, new {a=2,b="giraffe"}};
ILookup<int,string> lookup = myData.ToLookup(x => x.a, x => x.b);
IEnumerable<string> allOnes = lookup[1]; //enumerable of 2 items, frog and cat
ILookup是一种不可变数据结构,允许每个键有多个值。如果您需要在不同时间添加项目,可能没什么用处,但如果您预先拥有所有数据,这绝对是可行的方法。
答案 8 :(得分:0)
以下是一个答案的许多变体:)我是另一个,它使用扩展机制作为舒适的执行方式(方便):
public static void AddToList<T, U>(this IDictionary<T, List<U>> dict, T key, U elementToList)
{
List<U> list;
bool exists = dict.TryGetValue(key, out list);
if (exists)
{
dict[key].Add(elementToList);
}
else
{
dict[key] = new List<U>();
dict[key].Add(elementToList);
}
}
然后按如下方式使用它:
Dictionary<int, List<string>> dict = new Dictionary<int, List<string>>();
dict.AddToList(4, "test1");
dict.AddToList(4, "test2");
dict.AddToList(4, "test3");
dict.AddToList(5, "test4");
答案 9 :(得分:0)
NuGet包Microsoft Experimental Collections包含一个类MultiValueDictionary
,它可以完全满足您的需求。
Here是该软件包创建者的博客文章,进一步描述了它。
Here是另一篇博文,如果你感到好奇的话。
使用示例:
MultiDictionary<string, int> myDictionary = new MultiDictionary<string, int>();
myDictionary.Add("key", 1);
myDictionary.Add("key", 2);
myDictionary.Add("key", 3);
//myDictionary["key"] now contains the values 1, 2, and 3
答案 10 :(得分:0)
我试图将List添加到字典中的现有密钥并达到以下解决方案:
Dictionary<string,List<string>> NewParent = new Dictionary<string,List<string>>();
child = new List<string> ();
child.Add('SomeData');
NewParent["item1"].AddRange(child);
它不会显示任何异常,也不会替换以前的值。
答案 11 :(得分:0)
使用 AddOrUpdate 中的 ConcurrentDictionary 有一种“单命令行”方式:
using System.Linq;
using System.Collections.Generic;
using System.Collections.Concurrent;
...
var dictionary = new ConcurrentDictionary<string, IEnumerable<string>>();
var itemToAdd = "item to add to key-list";
dictionary.AddOrUpdate("key", new[]{itemToAdd}, (key,list) => list.Append(itemToAdd));
// If "key" doesn't exist, creates it with a list containing itemToAdd as value
// If "key" exists, adds item to already existent list (third parameter)