Ronald Arndt

C# Snippet - GroupByGap

June 15, 2025

#csharp #snippet #linq

Snippet C# - GroupByGap

June 15, 2025

This snippet demonstrates how to group elements of a list based on a gap interval between them. It is useful when you want to group numbers or objects that are close to each other.

In this example, we use an expression to select a DateTime property from each item and group the items that are within a specified maximum interval, but you can adapt it for other data types as needed.

public static List<List<T>> GroupByGap<T>(T[] items, Expression<Func<T, DateTime>> selector, TimeSpan maxGap)
{
if (items == null || items.Length == 0)
{
return [];
}
var sorted = items.AsQueryable().OrderBy(selector).ToArray();
var groups = new List<List<T>>();
var currentGroup = new List<T> { sorted[0] };
var selectorFunc = selector.Compile();
for (var i = 1; i < sorted.Length; i++)
{
if (selectorFunc(sorted[i]) - selectorFunc(sorted[i - 1]) <= maxGap)
{
currentGroup.Add(sorted[i]);
}
else
{
groups.Add(currentGroup);
currentGroup = [sorted[i]];
}
}
groups.Add(currentGroup);
return groups;
}

Usage

var items = new[]
{
new { Id = 1, Date = new DateTime(2023, 1, 1) },
new { Id = 2, Date = new DateTime(2023, 1, 2) },
new { Id = 3, Date = new DateTime(2023, 1, 5) },
new { Id = 4, Date = new DateTime(2023, 1, 10) },
};
var groupedItems = GroupByGap(items, x => x.Date, TimeSpan.FromDays(2));
foreach (var group in groupedItems)
{
Console.WriteLine($"Group: {string.Join(", ", group.Select(x => x.Id))}");
}
// Expcted output:
// Group: 1, 2
// Group: 3
// Group: 4

In this specific case, the items will be grouped into three lists: one containing IDs 1 and 2 (because they are within a 2-day interval), another containing ID 3 (because it is more than 2 days apart from the previous group), and another containing ID 4 (which is also more than 2 days apart from ID 3).