基本上,我想要一个类似于Dictionary的数据结构,但不同的是它的值也是唯一的。换句话说,它描绘了一对一的关系,而不是一对一的关系。
一个例子应该更好地解释。假设我将这个新的数据结构称为MyMapping,我想在其中保存已婚夫妇的名字:
MyMapping<string, string> myMapping = new MyMapping<string, string>();
myMapping.Add("Joe", "Ann");
myMapping.Add("Ann", "Joe");// not allowed
myMapping.Add("Joe", "Mary");// not allowed
myMapping.Add("William", "Katie");// ok
string partner = myMapping["Ann"];// result is Joe
partner = myMapping["Joe"];//result is Ann
答案 0 :(得分:1)
答案 1 :(得分:1)
我开始根据IDictionary为你构建一个TwoWayDictionary http://msdn.microsoft.com/en-us/library/s4ys34ea.aspx
//only one generic parameter needed, as key and value have same type.
public class TwoWayDictionary<TKey> : IDictionary<TKey, TKey>
{
private Dictionary<TKey, TKey> _primary;
private Dictionary<TKey, TKey> _secondary;
public TwoWayDictionary()
{
_primary = new Dictionary<TKey, TKey>();
_secondary = new Dictionary<TKey, TKey>();
}
public int Count {get{return _primary.Count;}}
public bool IsReadOnly {get{return _primary.IsReadOnly;}}
public TKey this[TKey key]
{
get
{
return this.GetValue(key);
}
set
{
this.Add(key, value);
}
}
public ICollection<TKey> Keys {get {return _primary.Keys;}}
public ICollection<TKey> Values {get {return _primary.Values;}}
private TKey GetValue(TKey key)
{
if (_primary.ContainsKey(key))
{
return _primary[key];
}
if (_secondary.ContainsKey(key))
{
return _secondary[key];
}
throw new KeyNotFoundException("key is not found");
}
public void Add(KeyValuePair<TKey, TKey> item)
{
this.Add(item.Key, item.Value);
}
public void Add(TKey key, TKey value)
{
if (key == null || value == null)
{
throw new ArguementNullException("key or value is null");
}
if (_primary.ContainsKey(key) || _secondary.ContainsKey(key)
|| _primary.ContainsKey(value) || _secondary.ContainsKey(value))
{
throw new ArgumentException("Item with same key or value already exists");
}
_primary.Add(key, value);
_secondary.Add(value, key);
}
public void Clear()
{
_primary.Clear();
_secondary.Clear();
}
public void Contains(KeyValuePair<TKey, TKey> item)
{
return _primary.Contains(item) || _secondary.Contains(item);
}
public void ContainsKey(TKey key)
{
return _primary.ContainsKey(key) || _secondary.ContainsKey(key);
}
public void CopyTo(KeyValuePair<TKey, TKey>[] array, int arrayIndex)
{
return _primary.CopyTo(array, arrayIndex);
}
... TODO finish implementing IDictionary
答案 2 :(得分:0)
不需要两个字典 - 带HashSet的字典就足够了。 HashSet当然会保留并保护这些值。
编辑:评论中有关问题的其他解释
新集合将包含Dictionary和HashSet的实例,如下所示:
class UniqueValueDictionary<TKey, TValue>
{
//...
private Dictionary<TKey, TValue> dictionary;
private HashSet<TValue> valueSet;
}
插入字典时,验证该值是否已存在:
public void Add(TKey key, TValue value)
{
if (valueSet.Contains(value))
{
//throw appropriate exception
}
dictionary.Add(key, value);
valueSet.Add(value);
}
删除时:
public void Remove(TKey key)
{
//check if key exists, throw exception if not
var value = dictionary[key];
dictionary.Remove(key);
valueSet.Remove(value);
}