C# Linq double groupby need min/max for hourly values once per day

I have been playing around with this for awhile now and can't quite get the result I am looking for.

I have an object like this:

public class Point
{
    public string Tag {get;set;}
    public DateTime Time {get;set;}
    public int Value {get;set;}
}

Each tag will have 24 values per day (one per hour). Data will look like this (Tag / Time / value):

x / 5-15-2015 - 0100 / 10 
x / 5-15-2015 - 0200 / 20 
x / 5-15-2015 - 0300 / 30 
y / 5-15-2015 - 0100 / 20 
y / 5-15-2015 - 0200 / 30 
x / 5-16-2015 - 0100 / 10 

for example...

I would like to sort by Tag and date, then get the min/max/avg for the 24 hrs in each day. The goal is to create the following object.

Public class NewPoint
{
    public string Tag {get;set;}
    public DateTime Date {get;set;}
    public int LowValue {get;set;}
    public int HighValue {get;set;}
    public int AvgValue {get;set;}
}

where the resulting objests would be (Tag / Date / LowValue / HighValue / AvgValue):

x / 5-15-2015 / 10 / 30 / 20 
y / 5-15-2015 / 20 / 30 / 25 
x / 5-16-2015 / 10 / 10 / 10 

I was having issues with:

group list by new {list.Tag, list.Time.ToString("d") } into dateGroup

I also think I am going to need two linq statements. One to group by the tag and date to find the min/max/avg for each tag/date, and another to grab date[0] (or the distinct date per tag) along with the min/max/avg to pass to the NewPoint object.

Advice is welcome, Thanks!

Jon Skeet
people
quotationmark

No need for two statements at all... nor using a string conversion. Just use the key of each group, and the DateTime.Date property:

var query = list.GroupBy(x => new { x.Tag, x.Time.Date })
                .Select(g => new NewPoint
                        {
                            Tag = g.Key.Tag,
                            Date = g.Key.Date,
                            LowValue = g.Min(x => x.Value),
                            HighValue = g.Max(x => x.Value),
                            AvgValue = (int) g.Average(x => x.Value)
                        });

The cast for AvgValue is required because the return type of Average is double - you might want to consider changing your property type instead.

people

See more on this question at Stackoverflow