Advertisement
L_B

TakeTopN

L_B
Dec 9th, 2012
169
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 2.26 KB | None | 0 0
  1.     public static class LinqExtensions
  2.     {
  3.         public static IEnumerable<T> TakeTopN<T, TKey>(this IEnumerable<T> list, int n, Func<T, TKey> keySelector, bool ascending = true) where TKey : IComparable<TKey>
  4.         {
  5.             IComparer<TKey> comparer = Comparer<TKey>.Default;
  6.             if (ascending == false) comparer = new ReverseComparer<TKey>(comparer);
  7.  
  8.             List<T> values = new List<T>(n + 1);
  9.             List<TKey> keys = new List<TKey>(n + 1);
  10.  
  11.             TKey max = keySelector(list.First());
  12.  
  13.             foreach (var item in list)
  14.             {
  15.                 var key = keySelector(item);
  16.  
  17.                 if (keys.Count < n)
  18.                 {
  19.                     int index = FindIndex<TKey>(keys, key, comparer);
  20.                     keys.Insert(index, key);
  21.                     values.Insert(index, item);
  22.                     max = keySelector(values[values.Count - 1]);
  23.                     continue;
  24.                 }
  25.  
  26.                 if (comparer.Compare(key,max) < 0)
  27.                 {
  28.                     int index = FindIndex<TKey>(keys, key, comparer);
  29.                     keys.Insert(index, key);
  30.                     values.Insert(index, item);
  31.                     if (keys.Count > n)
  32.                     {
  33.                         keys.RemoveAt(n);
  34.                         values.RemoveAt(n);
  35.                     }
  36.                     max = keySelector(values[values.Count - 1]);
  37.                 }
  38.             }
  39.  
  40.             return values;
  41.         }
  42.  
  43.         //Needed for stable sort...
  44.         private static int FindIndex<TKey>(List<TKey> keys, TKey key, IComparer<TKey> comparer) where TKey : IComparable<TKey>
  45.         {
  46.             int index = keys.BinarySearch(key, comparer);
  47.             if (index < 0) index = ~index;
  48.             while (index < keys.Count && comparer.Compare(keys[index],key) == 0) index++;
  49.             return index;
  50.         }
  51.  
  52.         class ReverseComparer<T> : IComparer<T>
  53.         {
  54.             IComparer<T> _Comparer;
  55.  
  56.             public ReverseComparer(IComparer<T> comparer)
  57.             {
  58.                 _Comparer = comparer;
  59.             }
  60.  
  61.             public int Compare(T x, T y)
  62.             {
  63.                 return _Comparer.Compare(y, x);
  64.             }
  65.         }
  66.     }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement