#if FAT using System; using System.Collections.Generic; using System.Linq; using LinqInternal.Collections.Specialized; namespace LinqInternal.Collections { internal static partial class Extensions { public static IEnumerable> GroupProgressiveBy(this IEnumerable source, Func keySelector) { return GroupProgressiveBy(source, keySelector, null); } public static IEnumerable> GroupProgressiveBy(this IEnumerable source, Func keySelector, IEqualityComparer comparer) { if (source == null) { throw new ArgumentNullException("source"); } if (keySelector == null) { throw new ArgumentNullException("keySelector"); } return CreateGroupByIterator(source, keySelector, comparer); } public static IEnumerable> GroupProgressiveBy(this IEnumerable source, Func keySelector, Func elementSelector) { return GroupProgressiveBy(source, keySelector, elementSelector, null); } public static IEnumerable> GroupProgressiveBy(this IEnumerable source, Func keySelector, Func resultSelector, IEqualityComparer comparer) { if (source == null) { throw new ArgumentNullException("source"); } if (keySelector == null) { throw new ArgumentNullException("keySelector"); } if (resultSelector == null) { throw new ArgumentNullException("resultSelector"); } return CreateGroupByIterator(source, keySelector, resultSelector, comparer); } public static IEnumerable GroupProgressiveBy(this IEnumerable source, Func keySelector, Func elementSelector, Func, TResult> resultSelector) { return GroupProgressiveBy(source, keySelector, elementSelector, resultSelector, null); } public static IEnumerable GroupProgressiveBy(this IEnumerable source, Func keySelector, Func elementSelector, Func, TResult> resultSelector, IEqualityComparer comparer) { if (source == null) { throw new ArgumentNullException("source"); } if (keySelector == null) { throw new ArgumentNullException("keySelector"); } if (elementSelector == null) { throw new ArgumentNullException("elementSelector"); } if (resultSelector == null) { throw new ArgumentNullException("resultSelector"); } return CreateGroupByIterator(source, keySelector, elementSelector, resultSelector, comparer); } public static IEnumerable GroupProgressiveBy(this IEnumerable source, Func keySelector, Func, TResult> resultSelector) { return GroupProgressiveBy(source, keySelector, resultSelector, null); } public static IEnumerable GroupProgressiveBy(this IEnumerable source, Func keySelector, Func, TResult> resultSelector, IEqualityComparer comparer) { if (source == null) { throw new ArgumentNullException("source"); } if (keySelector == null) { throw new ArgumentNullException("keySelector"); } if (resultSelector == null) { throw new ArgumentNullException("resultSelector"); } return CreateGroupByIterator(source, keySelector, resultSelector, comparer); } } internal static partial class Extensions { //GroupBy progressive implementation private static IEnumerable> CreateGroupByIterator(this IEnumerable source, Func keySelector, IEqualityComparer comparer) { // NOTICE this method has no null check var groups = new Dictionary>(comparer); var nullList = new List(); var counter = 0; var nullCounter = -1; foreach (TSource element in source) { var key = keySelector(element); if (ReferenceEquals(key, null)) { nullList.Add(element); if (nullCounter == -1) { nullCounter = counter; counter++; } } else { List group; if (!groups.TryGetValue(key, out group)) { group = new List(); groups.Add(key, group); counter++; } group.Add(element); } } counter = 0; foreach (var group in groups) { if (counter == nullCounter) { yield return new Grouping(default(TKey), nullList); counter++; } yield return new Grouping(group.Key, group.Value); counter++; } if (counter == nullCounter) { yield return new Grouping(default(TKey), nullList); // counter++; } } private static IEnumerable> CreateGroupByIterator(this IEnumerable source, Func keySelector, Func elementSelector, IEqualityComparer comparer) { // NOTICE this method has no null check var groups = new Dictionary>(comparer); var nullList = new List(); var counter = 0; var nullCounter = -1; foreach (TSource item in source) { var key = keySelector(item); var element = elementSelector(item); if (ReferenceEquals(key, null)) { nullList.Add(element); if (nullCounter == -1) { nullCounter = counter; counter++; } } else { List group; if (!groups.TryGetValue(key, out group)) { group = new List(); groups.Add(key, group); counter++; } group.Add(element); } } counter = 0; foreach (var group in groups) { if (counter == nullCounter) { yield return new Grouping(default(TKey), nullList); counter++; } yield return new Grouping(group.Key, group.Value); counter++; } if (counter == nullCounter) { yield return new Grouping(default(TKey), nullList); // counter++; } } private static IEnumerable CreateGroupByIterator(this IEnumerable source, Func keySelector, Func elementSelector, Func, TResult> resultSelector, IEqualityComparer comparer) { // NOTICE this method has no null check var groups = GroupProgressiveBy(source, keySelector, elementSelector, comparer); foreach (IGrouping group in groups) { yield return resultSelector(group.Key, group); } } private static IEnumerable CreateGroupByIterator(this IEnumerable source, Func keySelector, Func, TResult> resultSelector, IEqualityComparer comparer) { // NOTICE this method has no null check var groups = GroupProgressiveBy(source, keySelector, comparer); foreach (IGrouping group in groups) { yield return resultSelector(group.Key, group); } } } } #endif