Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- public static class LinqExtensions
- {
- public static IEnumerable<T> TakeTopN<T, TKey>(this IEnumerable<T> list, int n, Func<T, TKey> keySelector, bool ascending = true) where TKey : IComparable<TKey>
- {
- IComparer<TKey> comparer = Comparer<TKey>.Default;
- if (ascending == false) comparer = new ReverseComparer<TKey>(comparer);
- List<T> values = new List<T>(n + 1);
- List<TKey> keys = new List<TKey>(n + 1);
- TKey max = keySelector(list.First());
- foreach (var item in list)
- {
- var key = keySelector(item);
- if (keys.Count < n)
- {
- int index = FindIndex<TKey>(keys, key, comparer);
- keys.Insert(index, key);
- values.Insert(index, item);
- max = keySelector(values[values.Count - 1]);
- continue;
- }
- if (comparer.Compare(key,max) < 0)
- {
- int index = FindIndex<TKey>(keys, key, comparer);
- keys.Insert(index, key);
- values.Insert(index, item);
- if (keys.Count > n)
- {
- keys.RemoveAt(n);
- values.RemoveAt(n);
- }
- max = keySelector(values[values.Count - 1]);
- }
- }
- return values;
- }
- //Needed for stable sort...
- private static int FindIndex<TKey>(List<TKey> keys, TKey key, IComparer<TKey> comparer) where TKey : IComparable<TKey>
- {
- int index = keys.BinarySearch(key, comparer);
- if (index < 0) index = ~index;
- while (index < keys.Count && comparer.Compare(keys[index],key) == 0) index++;
- return index;
- }
- class ReverseComparer<T> : IComparer<T>
- {
- IComparer<T> _Comparer;
- public ReverseComparer(IComparer<T> comparer)
- {
- _Comparer = comparer;
- }
- public int Compare(T x, T y)
- {
- return _Comparer.Compare(y, x);
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement