Paul
Paul

Reputation: 217

Linq Grouping and averages

I have two objects one is a car object and the other object I use to log how many car objects are on shift and record what properties these cars have.

public class Car
{
    public int Id { get; set; }
    public bool OnShift { get; set; }
    public bool HasExtraBaggageSpace { get; set; }


}

public class Log
{
    public DateTime TimeStamp { get; set; }
    public int CarId { get; set; }
    public bool HasExtraBaggageSpace { get; set; }

}

Every five minutes the app selects all the cars on shift and writes the information to a log object and inserts them into a List Logs.

After three weeks of logging I would now like to return a number which reflects the average of the last three weeks . Example: How many cars with HasExtraBaggageSpace can I expect on a thursday at 14:00.

public class myApp {

  public class AverageReturnArgs
     {
       public int Hour { get; set; }
       public int Minute { get; set; }
       public int Count { get; set; }

     }



    public AverageReturnArgs GetAverage(List<Log> logs, DateTime TimeReq)
    {
        int hour = TimeReq.Hour;
        int min = TimeReq.Minute;
        var average = logs.GroupBy(grpByHourMin => new
        {
            hour = grpByHourMin.TimeStamp.Hour,
            min = grpByHourMin.TimeStamp.Minute
        }).Select(av => new AverageReturnArgs()
        {
            Hour = av.Key.hour,
            Minute = av.Key.min,
            Count = av.Average(x => x.HasExtraBaggageSpace)
        });
    }
}

This is producing a compiler error. Count = av.Average(x => x.HasExtraBaggageSpace)

Any ideas how I could accomplish this?

Upvotes: 0

Views: 116

Answers (1)

Ndech
Ndech

Reputation: 965

How would you calculate the average of boolean values ? I think the Count aggregate should be what you are looking for:

Count = av.Count(x => x.HasExtraBaggageSpace)

EDIT If you mean to calculate the percentage of cars having ExtraBaggageSpace you may try something like this :

Count = av.Average(x => x.HasExtraBaggageSpace ? 1 : 0)

With use of the ternary operator this expression convert your boolean value to an integer and calculate the average (that will be a Double).

EDIT 2

Here is what your line should look like. Count should be made of type Double.

Count = av.Average(x => av.Count(y=>y.HasExtraBaggageSpace))

EDIT 3

Ok the logic was all wrong :

public AverageReturnArgs GetAverage(List<Log> logs, DateTime TimeReq)
{
    int hour = TimeReq.Hour;
    int min = TimeReq.Minute;
    var average = logs
    .Where(log => log.TimeStamp.Hour == hour && log.TimeStamp.Minute == min)
    .GroupBy(grp => grp.TimeStamp)
    .Select(av => new AverageReturnArgs()
    {
        Hour = hour,
        Minute = min,
        Count = av.Average(x => av.Count(y=>y.HasExtraBaggageSpace))
    });
}

Upvotes: 2

Related Questions