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!

-------------Problems Reply------------

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.

Something like this is what you're after methinks:

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

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

public List<NewPoint> Summary(List<Point> list)
{
return list
.GroupBy(p => new {p.Tag, p.Time.Date})
.Select(grp => new NewPoint()
{
Tag = grp.Key.Tag,
Date = grp.Key.Date,
LowValue = grp.Min(p => p.Value),
HighValue = grp.Max(p => p.Value),
AvgValue = grp.Average(p => p.Value),
})
.ToList();
}

Note the average is a double so NewPoint is updated to reflect that.

Category:c# Views:0 Time:2018-06-12
Tags: linq date

Related post

Copyright (C) dskims.com, All Rights Reserved.

processed in 2.941 (s). 12 q(s)