Skip to content

Instantly share code, notes, and snippets.

@Workshopshed
Last active November 6, 2019 22:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Workshopshed/53da64d40b94a2b6f7d924bffb611798 to your computer and use it in GitHub Desktop.
Save Workshopshed/53da64d40b94a2b6f7d924bffb611798 to your computer and use it in GitHub Desktop.
ConsecutiveGroupBy using Generics
//A consecutive groupby in Linq and C#
//proof of concept for merging some date range like objects
//Based on https://www.daniweb.com/programming/software-development/code/488977/linq-consecutive-groupby
using System;
using System.Collections.Generic;
using System.Linq;
namespace ConsecutiveGroupBy {
public static class Extensions {
public static IQueryable<T> ConsecutiveGroupBy<T, TProp>(
this IQueryable<T> instance,
Func<T, TProp> orderBy,
Func<T, T, bool> isAdjacentFunc,
Action<T, T> mergeFunc)
{
List<T> result = new List<T>();
if (instance != null) {
result =
instance
.OrderBy(orderBy)
.Aggregate(
new List<T>(), (list, item) => {
if (list.Count == 0 || !isAdjacentFunc(list.Last(), item)) {
list.Add(item);
}
else {
mergeFunc(list.Last(),item);
}
return list;
});
}
return result.AsQueryable();
}
}
public class TestClass {
public int From { get; set; }
public int To { get; set; }
}
class Program {
static void Main() {
var data = new List<TestClass>
{
new TestClass { From = 26, To = 30 },
new TestClass { From = 21, To = 25 },
new TestClass { From = 15, To = 20 },
new TestClass { From = 8, To = 9 },
new TestClass { From = 8, To = 11 },
new TestClass { From = 4, To = 7 },
new TestClass { From = 1, To = 2 }
}.AsQueryable();
var consecutiveKeys = data.ConsecutiveGroupBy(item => item.From,
(current, next) => current.To + 1 >= next.From,
(a, b) => { if (a.To < b.To) { a.To = b.To; } }
);
foreach (var k in consecutiveKeys) {
Console.WriteLine("{0} - {1}", k.From,k.To);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment