public static IEnumerable <M> GetNSmallest <M>(this IComparer <M> g, IEnumerable <M> source, int n) { if (n < 0) { return(g.GetNLargest(source, -n)); } if (n == 0) { return(Enumerable.Empty <M>()); } var sourceList = source.ToList(); n = Math.Min(sourceList.Count, n); var resSet = sourceList.Take(n).ToList(); var currentMax = g.Max(resSet); foreach (var t in sourceList.Skip(n)) { if (g.Compare(t, currentMax) >= 0) { continue; } resSet.Remove(currentMax); resSet.Add(t); currentMax = g.Max(resSet); } return(resSet.OrderBy(i => i, g)); }