Mercury library  1.0
Translation of CFG grammars into an object model (Bachelor's thesis).
 All Classes Namespaces Files Functions Variables Enumerations Enumerator Properties
MultiDictionary.cs
Go to the documentation of this file.
1 using System;
2 using System.Collections;
3 using System.Collections.Generic;
4 using System.Linq;
5 
6 namespace Mercury.Nucleus.Collections
7 {
8 //=============================================================================
9 // IReadOnlyMultiDictionary
10 //=============================================================================
11 
18  public interface IReadOnlyMultiDictionary<TKey, TValue> : IEnumerable<KeyValuePair<TKey, TValue>>
19  {
24  bool Contains(TKey key, TValue value);
25 
33  bool ContainsKey(TKey key);
34 
42  bool TryGetValue(TKey key, out IReadOnlyList<TValue> collection);
43 
45  ICollection<TKey> Keys { get; }
46 
51  IReadOnlyList<TValue> this[TKey key] { get; }
52  }
53 
54 //=============================================================================
55 // IMultiDictionary
56 //=============================================================================
57 
64  public interface IMultiDictionary<TKey, TValue> : IReadOnlyMultiDictionary<TKey, TValue>
65  {
78  bool Add(TKey key, TValue value);
79 
91  bool Add(KeyValuePair<TKey, TValue> tuple);
92 
106  bool Add(TKey key, IEnumerable<TValue> values);
107 
109  void Clear();
110  }
111 
112 //=============================================================================
113 // SetMultiDictionary
114 //=============================================================================
115 
127  public class SetMultiDictionary<TKey, TValue> :
128  IMultiDictionary<TKey, TValue>
129  {
130  //--[ Protected fields ]---------------------------------------------
131 
132  protected Dictionary<TKey, HashSet<TValue>> data
133  = new Dictionary<TKey, HashSet<TValue>>();
134 
135  //--[ Interface implementation ]-------------------------------------
136 
137  #region [ IMultiDictionary ]
138 
139  public bool Add(TKey key, TValue value)
140  {
141  HashSet<TValue> set;
142  if (data.TryGetValue(key, out set))
143  return set.Add(value);
144 
145  data.Add(key, new HashSet<TValue> { value });
146  return true;
147  }
148 
149  public bool Add(KeyValuePair<TKey, TValue> pair)
150  { return this.Add(pair.Key, pair.Value); }
151 
152  public bool Add(TKey key, IEnumerable<TValue> values)
153  {
154  if (data.ContainsKey(key)) return false;
155 
156  data.Add(key, new HashSet<TValue>(values));
157  return true;
158  }
159 
160  public bool Contains(TKey key, TValue value)
161  {
162  HashSet<TValue> set;
163  if (!data.TryGetValue(key, out set))
164  return false;
165 
166  return set.Contains(value);
167  }
168 
169  public bool ContainsKey(TKey key)
170  { return data.ContainsKey(key); }
171 
172  public void Clear()
173  { data.Clear(); }
174 
175  public bool TryGetValue(TKey key, out IReadOnlyList<TValue> collection)
176  {
177  if (key == null) throw new ArgumentNullException("key");
178 
179  HashSet<TValue> values = null;
180  bool r = data.TryGetValue(key, out values);
181  collection = values.ToList();
182  return r;
183  }
184 
185  public ICollection<TKey> Keys { get { return data.Keys; } }
186 
187  public IReadOnlyList<TValue> this[TKey key]
188  { get { return data[key].ToList(); } }
189 
190  #endregion
191 
192  #region [ IEnumerable ]
193 
194  public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
195  {
196  foreach(var pair in data)
197  foreach (var value in pair.Value)
198  yield return new KeyValuePair<TKey, TValue>(pair.Key, value);
199  }
200 
201  IEnumerator IEnumerable.GetEnumerator()
202  { return GetEnumerator() as IEnumerator; }
203 
204  #endregion
205 
206  }
207 
208 //=============================================================================
209 // ListMultiDictionary
210 //=============================================================================
211 
223  public class ListMultiDictionary<TKey, TValue> :
224  IMultiDictionary<TKey, TValue>
225  {
226  //--[ Protected fields ]---------------------------------------------
227 
228  private Dictionary<TKey, List<TValue>> data
229  = new Dictionary<TKey, List<TValue>>();
230 
231  //--[ Constructors ]-------------------------------------------------
232 
235  { }
236 
243  { foreach(var pair in source) Add(pair.Key, pair.Value); }
244 
245  //--[ Methods ]------------------------------------------------------
246 
251  public TValue GetValue(TKey key, int ix)
252  { return data[key][ix]; }
253 
257  public int GetValuesCount(TKey key)
258  { return data[key].Count; }
259 
260  //--[ Interface implementation ]-------------------------------------
261 
262  #region [ IMultiDictionary ]
263 
264  public virtual bool Add(TKey key, TValue value)
265  {
266  List<TValue> values = null;
267  if (data.TryGetValue(key, out values))
268  values.Add(value);
269  else
270  data.Add(key, new List<TValue> { value });
271 
272  return true;
273  }
274 
275  public virtual bool Add(KeyValuePair<TKey, TValue> pair)
276  { return this.Add(pair.Key, pair.Value); }
277 
278  public virtual bool Add(TKey key, IEnumerable<TValue> values)
279  {
280  if (data.ContainsKey(key)) return false;
281 
282  data.Add(key, new List<TValue>(values));
283  return true;
284  }
285 
286  public virtual bool Contains(TKey key, TValue value)
287  {
288  List<TValue> list;
289  if (!data.TryGetValue(key, out list))
290  return false;
291 
292  return list.Contains(value);
293  }
294 
295  public bool ContainsKey(TKey key)
296  { return data.ContainsKey(key); }
297 
298  public virtual void Clear()
299  { data.Clear(); }
300 
301  public bool TryGetValue(TKey key, out IReadOnlyList<TValue> collection)
302  {
303  if (key == null) throw new ArgumentNullException("key");
304 
305  List<TValue> values = null;
306  bool r = data.TryGetValue(key, out values);
307  collection = values;
308  return r;
309  }
310 
311  public ICollection<TKey> Keys { get { return data.Keys; } }
312 
313  public IReadOnlyList<TValue> this[TKey key]
314  { get { return data[key]; } }
315 
316  #endregion
317 
318  #region [ IEnumerable ]
319 
320  public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
321  {
322  foreach(var pair in data)
323  for (int ix = 0; ix < pair.Value.Count; ++ix)
324  yield return new KeyValuePair<TKey, TValue>(pair.Key, pair.Value[ix]);
325  }
326 
327  IEnumerator IEnumerable.GetEnumerator()
328  { return GetEnumerator() as IEnumerator; }
329 
330  #endregion
331 
332  }
333 
334 //=============================================================================
335 // UniqueListMultiDictionary
336 //=============================================================================
337 
351  public class UniqueListMultiDictionary<TKey, TValue> :
352  ListMultiDictionary<TKey, TValue>, IMultiDictionary<TKey, TValue>
353  {
354  //--[ Protected fields ]---------------------------------------------
355 
356  protected SetMultiDictionary<TKey, TValue> data
358 
359  //--[ Overriden methods ]--------------------------------------------
360 
361  #region [ ListMultiDictionary ]
362 
363  public override bool Add(TKey key, TValue value)
364  { return data.Add(key, value) && base.Add(key, value); }
365 
366  public override bool Contains(TKey key, TValue value)
367  { return data.Contains(key, value); }
368 
369  public override void Clear()
370  { data.Clear(); base.Clear(); }
371 
372  #endregion
373 
374  }
375 }
bool TryGetValue(TKey key, out IReadOnlyList< TValue > collection)
Gets the value associated with the specified key.
bool ContainsKey(TKey key)
Indicates whether this collection contains the specified key.
override void Clear()
Removes the content of collection.
virtual void Clear()
Removes the content of collection.
virtual bool Add(TKey key, TValue value)
Adds the value to the dictionary. The actual behaviour and handling of duplicities is specified by an...
bool ContainsKey(TKey key)
Indicates whether this collection contains the specified key.
ListMultiDictionary(IMultiDictionary< TKey, TValue > source)
Creates a multidictionary initialized by values from another multidictionary.
virtual bool Add(TKey key, IEnumerable< TValue > values)
Adds the collection of values to the dictionary. If the key is already present, NO value is added an...
override bool Add(TKey key, TValue value)
Adds the value to the dictionary. The actual behaviour and handling of duplicities is specified by an...
bool Add(KeyValuePair< TKey, TValue > pair)
Adds the value to the dictionary. The actual behaviour and handling of duplicities is specified by an...
int GetValuesCount(TKey key)
The size of underlying list.
bool Add(TKey key, IEnumerable< TValue > values)
Adds the collection of values to the dictionary. If the key is already present, NO value is added an...
Represents a multi-valued dictionary, in other words a map between a key and a collection of values...
IEnumerator< KeyValuePair< TKey, TValue > > GetEnumerator()
An implementation of IMultiDictionary{TKey,TValue} using T:System.Collections.Generic.HashSet{T} as an underlying collection of values.
ListMultiDictionary()
Default constructor, creates an empty dictionary
virtual bool Add(KeyValuePair< TKey, TValue > pair)
Adds the value to the dictionary. The actual behaviour and handling of duplicities is specified by an...
virtual bool Contains(TKey key, TValue value)
Indicates whether this collection contains the specified key and value.
bool Add(TKey key, TValue value)
Adds the value to the dictionary. The actual behaviour and handling of duplicities is specified by an...
TValue GetValue(TKey key, int ix)
Gets the value from the underlying list.
bool Contains(TKey key, TValue value)
Indicates whether this collection contains the specified key and value.
override bool Contains(TKey key, TValue value)
Indicates whether this collection contains the specified key and value.
IEnumerator< KeyValuePair< TKey, TValue > > GetEnumerator()
bool TryGetValue(TKey key, out IReadOnlyList< TValue > collection)
Gets the value associated with the specified key.