I\'m trying to understand how LINQ can be used to group data by intervals of time; and then ideally aggregate each group.
Finding numerous examples with explicit dat
A generalised solution:
static IEnumerable> GroupBy(this IOrderedEnumerable enumerable, TimeSpan timeSpan, Func predicate)
{
Grouping grouping = null;
foreach (var (a, dt) in from b in enumerable select (b, predicate.Invoke(b)))
{
if (grouping == null || dt > grouping.Key.End)
yield return grouping = new Grouping(new DateRange(dt, dt + timeSpan), a);
else
grouping.Add(a);
}
}
class Grouping : IGrouping
{
readonly List elements = new List();
public DateRange Key { get; }
public Grouping(DateRange key) => Key = key;
public Grouping(DateRange key, T element) : this(key) => Add(element);
public void Add(T element) => elements.Add(element);
public IEnumerator GetEnumerator()=> this.elements.GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}
class DateRange
{
public DateRange(DateTime start, DateTime end)
{
this.Start = start;
this.End = end;
}
public DateTime Start { get; set; }
public DateTime End { get; set; }
}
Test based on question (using AutoFixture library)
void Test()
{
var many = new Fixture().CreateMany(100);
var groups = many.OrderBy(a => a.timestamp).GroupBy(TimeSpan.FromDays(365), a => a.timestamp).Select(a => a.Average(b => b.value)).ToArray();
}
public class Sample
{
public DateTime timestamp;
public double value;
}