/// <summary>
        /// <para>
        /// Replacement for list.OrderBy(?).Take(n)
        /// </para>
        /// <para>
        /// 1- Low Memory usage (since this method requires only ~"2*n" elements be in memory)
        /// </para>
        /// 2- Speed up by an order of magnitude especially when the input is large.
        /// </summary>
        public static IEnumerable <T> TakeOrdered <T, TKey>(this IEnumerable <T> list, int n, Func <T, TKey> keySelector, bool ascending = true) where TKey : IComparable <TKey>
        {
            var pq = new MyPriorityQueue <T>(n,
                                             ascending
                        ?
                                             (Func <T, T, bool>)((a, b) => keySelector(a).CompareTo(keySelector(b)) >= 0)
                        :
                                             (Func <T, T, bool>)((a, b) => keySelector(a).CompareTo(keySelector(b)) < 0)
                                             );

            Stack <T> stack = new Stack <T>();

            int count = 0;

            foreach (T item in list)
            {
                pq.InsertWithOverflow(item);
                count++;
            }

            int min = Math.Min(count, n);

            for (int i = 0; i < min; i++)
            {
                stack.Push(pq.Pop());
            }

            for (int i = 0; i < min; i++)
            {
                yield return(stack.Pop());
            }
        }