Advertisement
Filkolev

First-Last-List

Sep 13th, 2015
176
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4.  
  5. using Wintellect.PowerCollections;
  6.  
  7. public class FirstLastList<T> : IFirstLastList<T>
  8.     where T : IComparable<T>
  9. {
  10.     private readonly LinkedList<T> elements = new LinkedList<T>();
  11.     private readonly SortedDictionary<T, List<LinkedListNode<T>>> nodes = new SortedDictionary<T, List<LinkedListNode<T>>>();
  12.     private readonly OrderedBag<T> orderedElements = new OrderedBag<T>();
  13.     private readonly OrderedBag<T> reversedOrderedElements = new OrderedBag<T>((e1, e2) => e2.CompareTo(e1));
  14.  
  15.     public void Add(T newElement)
  16.     {
  17.         var node = this.elements.AddLast(newElement);
  18.  
  19.         if (!this.nodes.ContainsKey(newElement))
  20.         {
  21.             this.nodes.Add(newElement, new List<LinkedListNode<T>>());
  22.         }
  23.  
  24.         this.nodes[newElement].Add(node);
  25.         this.orderedElements.Add(newElement);
  26.         this.reversedOrderedElements.Add(newElement);
  27.     }
  28.  
  29.     public int Count => this.orderedElements.Count;
  30.  
  31.     public IEnumerable<T> First(int count)
  32.     {
  33.         if (count > this.orderedElements.Count)
  34.         {
  35.             throw new ArgumentOutOfRangeException(nameof(count));
  36.         }
  37.  
  38.         return this.elements.Take(count);
  39.     }
  40.  
  41.     public IEnumerable<T> Last(int count)
  42.     {
  43.         if (count > this.orderedElements.Count)
  44.         {
  45.             throw new ArgumentOutOfRangeException(nameof(count));
  46.         }
  47.  
  48.         var result = new T[count];
  49.         var current = this.elements.Last;
  50.  
  51.         for (int i = 0; i < count; i++)
  52.         {
  53.             result[i] = current.Value;
  54.             current = current.Previous;
  55.         }
  56.  
  57.         return result;
  58.     }
  59.  
  60.     public IEnumerable<T> Min(int count)
  61.     {
  62.         if (count > this.orderedElements.Count)
  63.         {
  64.             throw new ArgumentOutOfRangeException(nameof(count));
  65.         }
  66.  
  67.         return this.orderedElements.Take(count);
  68.     }
  69.  
  70.     public IEnumerable<T> Max(int count)
  71.     {
  72.         if (count > this.orderedElements.Count)
  73.         {
  74.             throw new ArgumentOutOfRangeException(nameof(count));
  75.         }
  76.  
  77.         return this.reversedOrderedElements.Take(count);
  78.     }
  79.  
  80.     public int RemoveAll(T element)
  81.     {
  82.         var count = this.orderedElements.RemoveAllCopies(element);
  83.         this.reversedOrderedElements.RemoveAllCopies(element);
  84.  
  85.         if (count > 0)
  86.         {
  87.             var nodesToRemove = this.nodes[element];
  88.  
  89.             foreach (var linkedListNode in nodesToRemove)
  90.             {
  91.                 this.elements.Remove(linkedListNode);
  92.             }
  93.  
  94.             this.nodes.Remove(element);
  95.         }
  96.  
  97.         return count;
  98.     }
  99.  
  100.     public void Clear()
  101.     {
  102.         this.elements.Clear();
  103.         this.nodes.Clear();
  104.         this.orderedElements.Clear();
  105.         this.reversedOrderedElements.Clear();
  106.     }
  107. }
Advertisement
RAW Paste Data Copied
Advertisement