.NET基类库中是否有允许使用重复键的字典类?我发现的唯一解决方案是创建一个类,例如:
Dictionary>
但这对实际使用非常恼火.在Java中,我相信MultiMap可以实现这一点,但是在.NET中找不到模拟.
如果您使用的是.NET 3.5,请使用Lookup
该类.
编辑:您通常创建一个Lookup
使用Enumerable.ToLookup
.这确实假设您之后不需要更改它 - 但我通常发现它足够好.
如果不为你工作,我不认为有在框架中,这将有助于东西-和使用字典是好得不能再好:(
List类实际上非常适用于包含重复项的键/值集合,您希望迭代集合.例:
List> list = new List >(); // add some values to the collection here for (int i = 0; i < list.Count; i++) { Print(list[i].Key, list[i].Value); }
以下是使用List
public class ListWithDuplicates : List> { public void Add(string key, string value) { var element = new KeyValuePair (key, value); this.Add(element); } } var list = new ListWithDuplicates(); list.Add("k1", "v1"); list.Add("k1", "v2"); list.Add("k1", "v3"); foreach(var item in list) { string x = string.format("{0}={1}, ", item.Key, item.Value); }
输出k1 = v1,k1 = v2,k1 = v3
如果您使用字符串作为键和值,则可以使用System.Collections.Specialized.NameValueCollection,它将通过GetValues(字符串键)方法返回字符串值数组.
我刚刚遇到了PowerCollections库,其中包括一个名为MultiDictionary的类.这整齐地包装了这种类型的功能.
关于使用Lookup的非常重要的注意事项:
您可以Lookup(TKey, TElement)
通过调用ToLookup
实现的对象来创建a的实例IEnumerable(T)
没有公共构造函数来创建a的新实例Lookup(TKey, TElement)
.此外,Lookup(TKey, TElement)
对象是不可变的,也就是说,Lookup(TKey, TElement)
在创建对象后,无法在对象中添加或删除元素或键.
(来自MSDN)
我认为这对于大多数用途来说都是显示器.
我觉得像List
约伯这样的事情.
如果您使用的是> = .NET 4,则可以使用Tuple
Class:
// declaration var list = new List>>(); // to add an item to the list var item = Tuple >("key", new List
看看C5的 HashBag类.
“滚动自己的”字典版本很容易,该字典允许“重复键”条目。这是一个简单的简单实现。您可能要考虑增加对上大多数(如果不是全部)的支持IDictionary
。
public class MultiMap{ private readonly Dictionary > storage; public MultiMap() { storage = new Dictionary >(); } public void Add(TKey key, TValue value) { if (!storage.ContainsKey(key)) storage.Add(key, new List ()); storage[key].Add(value); } public IEnumerable Keys { get { return storage.Keys; } } public bool ContainsKey(TKey key) { return storage.ContainsKey(key); } public IList this[TKey key] { get { if (!storage.ContainsKey(key)) throw new KeyNotFoundException( string.Format( "The given key {0} was not found in the collection.", key)); return storage[key]; } } }
有关如何使用它的快速示例:
const string key = "supported_encodings"; var map = new MultiMap(); map.Add(key, Encoding.ASCII); map.Add(key, Encoding.UTF8); map.Add(key, Encoding.Unicode); foreach (var existingKey in map.Keys) { var values = map[existingKey]; Console.WriteLine(string.Join(",", values)); }