是否有C#数据结构将键映射到多个值?我有一个项目集合,我想按名称键入;但是,名称并不是唯一的。 Hashtable和Dictionary只允许使用唯一键。查找似乎接近我想要的;但是,它不可变。
是否存在我缺少的内置数据结构,或者我是否需要自己构建一个?
答案 0 :(得分:8)
您要找的是multimap。
您可能需要查看answer to this question。
您可能还想查看C5 Generic Collection library,它是免费的,并且具有多地图的实现。
如果你想要自己动手,一个简单的起点是列表:
Dictionary<TKey,List<TValue>>
但是,你不能以正常方式添加到这样的字典中。您必须首先检查密钥是否已存在,如果是,则获取值(列表)并添加到该密钥。否则,您需要创建列表并使用值填充它。
如果您如此倾向,我建议您考虑使用一组扩展方法来简化添加/删除操作:
public static class MultimapExt
{
public static void Add<TKey,TValue>(
this Dictionary<TKey,List<TValue>> dictionary, TKey key, TValue value )
{
List<TValue> valueList;
if( !dictionary.TryGetValue( key, out valueList )
{
valueList = new List<TValue>();
dictionary.Add( key, valueList );
}
valueList.Add( value );
}
public static void Remove<TKey,TValue>(
this Dictionary<TKey,List<TValue>> dictionary, TKey key, TValue value )
{
List<TValue> valueList;
if( dictionary.TryGetValue( key, out valueList ) )
{
valueList.Remove( value );
if( valueList.Count == 0 )
dictionary.Remove( key );
}
}
}
答案 1 :(得分:2)
LBushkin's answer是个好人。但是,通过删除不必要的限制来使用Dictionary<TKey, List<TValue>>
(这样你也可以使用SortedDictionary<TKey, LinkedList<TValue>>
)通过一些精心选择的通用约束,你可以使它更灵活一些:
public static class MultimapExt
{
public static void Add<TKey, TValue, TCollection>(
this IDictionary<TKey, TCollection> dictionary,
TKey key,
TValue value
) where TCollection : ICollection<TValue>, new()
{
TCollection collection;
if(!dictionary.TryGetValue(key, out collection)
{
collection = new TCollection();
dictionary.Add(key, collection);
}
collection.Add(value);
}
public static bool Remove<TKey, TValue, TCollection>(
this IDictionary<TKey, TCollection> dictionary,
TKey key,
TValue value
) where TCollection : ICollection<TValue>
{
TCollection collection;
if(dictionary.TryGetValue(key, out collection))
{
bool removed = collection.Remove(value);
if(collection.Count == 0)
dictionary.Remove(key);
return removed;
}
return false;
}
}
答案 2 :(得分:0)
如何使用字典IList<YOUR_VALUE_TYPE>
?