public static IGroupByManyResult <T> GroupByMany <T>(this IEnumerable <T> source, IEqualityComparer <object> equalityComparer, params Expression <Func <T, object> >[] keySelectors) { var groups = GroupByMany(string.Empty, source, equalityComparer, keySelectors).ToList(); var group = new GroupByManyResult <T>(groups) { Key = string.Empty, Count = groups.Count, Details = groups.SelectMany(g => g.Details) }; foreach (var subGroup in groups) { subGroup.Parent = group; } return(group); }
private static List <GroupByManyResult <T> > GroupByMany <T>(string parentKey, IEnumerable <T> source, IEqualityComparer <object> equalityComparer, params Expression <Func <T, object> >[] keySelectors) { if (!keySelectors.Any()) { return(new List <GroupByManyResult <T> >()); } var curSelector = keySelectors.First(); var nextSelectors = keySelectors.Skip(1).ToArray(); var index = 0; var results = new List <GroupByManyResult <T> >(); var groupName = GetName(curSelector); var compiled = curSelector.Compile(); foreach (var group in source .GroupBy(compiled, equalityComparer) .Where(g => g.Key != null)) { var key = string.IsNullOrEmpty(parentKey) ? index++.ToString() : $"{parentKey}-{index++}"; var subGroups = GroupByMany(key, group, equalityComparer, nextSelectors); var result = new GroupByManyResult <T>(subGroups) { Key = key, GroupName = groupName, Item = group.Key, Count = group.Count(), Details = group, FirstDetail = group.FirstOrDefault(), }; foreach (var subGroup in subGroups) { subGroup.Parent = result; } results.Add(result); } return(results); }