1
0

Lookup.cs 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. // Licensed to the .NET Foundation under one or more agreements.
  2. // The .NET Foundation licenses this file to you under the MIT License.
  3. // See the LICENSE file in the project root for more information.
  4. using System.Collections;
  5. using System.Collections.Generic;
  6. using System.Linq;
  7. namespace System.Reactive
  8. {
  9. internal sealed class Lookup<K, E> : ILookup<K, E>
  10. {
  11. private readonly Dictionary<K, List<E>> d;
  12. public Lookup(IEqualityComparer<K> comparer)
  13. {
  14. d = new Dictionary<K, List<E>>(comparer);
  15. }
  16. public void Add(K key, E element)
  17. {
  18. if (!d.TryGetValue(key, out var list))
  19. d[key] = list = new List<E>();
  20. list.Add(element);
  21. }
  22. public bool Contains(K key) => d.ContainsKey(key);
  23. public int Count => d.Count;
  24. public IEnumerable<E> this[K key]
  25. {
  26. get
  27. {
  28. if (!d.TryGetValue(key, out var list))
  29. return Enumerable.Empty<E>();
  30. return Hide(list);
  31. }
  32. }
  33. private IEnumerable<E> Hide(List<E> elements)
  34. {
  35. foreach (var x in elements)
  36. yield return x;
  37. }
  38. public IEnumerator<IGrouping<K, E>> GetEnumerator()
  39. {
  40. foreach (var kv in d)
  41. yield return new Grouping(kv);
  42. }
  43. private sealed class Grouping : IGrouping<K, E>
  44. {
  45. private readonly KeyValuePair<K, List<E>> kv;
  46. public Grouping(KeyValuePair<K, List<E>> kv)
  47. {
  48. this.kv = kv;
  49. }
  50. public K Key => kv.Key;
  51. public IEnumerator<E> GetEnumerator() => kv.Value.GetEnumerator();
  52. IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
  53. }
  54. IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
  55. }
  56. }