HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

Average value for each row

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
eachaveragevalueforrow

Problem

I have these classes:

public class DelayReason
{
    public virtual ICollection WorkOrders { get; set; }

}
public class WorkOrder 
{
    public virtual ICollection DelayReasons { get; set; }
 //other fields
}


Each DelayReason has 0..* WorkOrders and it's the same for WorkOrders.

This is a data sample:

To do this, I've written this code. Can I optimize that?

public void DelayReasonAverage()
    {
        List result = new List();

        var reasons = _delayReasons.GroupBy(row => row, (k, t) => new
        {
            delayId = k.Id,
            delayTitle = k.Title,
            workOrders = k.WorkOrders,
            count = t.Count()
        }).OrderByDescending(row => row.count).ToList();

        reasons.ForEach(row =>
        {
            var workOrders = row.workOrders.ToList();

            ReportVM reportObj = new ReportVM() { DelayTitle= row.delayTitle };

            for (int i = 0; i  i)
                    reportObj.Count += workOrders[i].CreatedOn.DiffDays(workOrders[i + 1].CreatedOn);
            }
            reportObj.Count = reportObj.Count / row.count;
            result.Add(reportObj);
        });
    }


DiffDays extension Method:

public static int DiffDays(this DateTime current,DateTime to)
 {
    return to.Subtract(current).Days;
 }


The final results look like this:

Solution

While the logic of this:

for (int i = 0; i  i)
        reportObj.Count += workOrders[i].CreatedOn.DiffDays(workOrders[i + 1].CreatedOn);
}
reportObj.Count = reportObj.Count / row.count;


is valid. I think the for loop might not be necessary. You should be able to take the difference from the first to last:

reportObj.Count = workOrders[0].CreatedOn.DiffDays(workOrders[workOrders.Count - 1].CreatedOn) / row.count;


In looking at the rest of that method it looks like the LINQ queries can be simplified quite a bit. Something like this should work:

public List DelayReasonAverage()
{
    return (from DelayReason dr in _delayReasons
            let row = new
            {
                delayId = dr.Id,
                delayTitle = dr.Title,
                workOrders = dr.WorkOrders.ToList(),
                count = _delayReasons.Count()
            }
            orderby row.count descending
            let reportObj = new ReportVM()
            {
                DelayTitle = row.delayTitle,
                Count = (int)Math.Round(row.workOrders[0].CreatedOn.DiffDays
                (row.workOrders[row.workOrders.Count - 1].CreatedOn) / (double)row.count)
            }
            select reportObj).ToList();
}


I noticed your post has this method as void, but it's creating a list, so I changed the signature to reflect that. I also changed the way the average is calculated, by using Math.Round to get a more accurate reflection of the actual average.

Code Snippets

for (int i = 0; i < workOrders.Count; i++)
{
    if (workOrders.Count - 1 > i)
        reportObj.Count += workOrders[i].CreatedOn.DiffDays(workOrders[i + 1].CreatedOn);
}
reportObj.Count = reportObj.Count / row.count;
reportObj.Count = workOrders[0].CreatedOn.DiffDays(workOrders[workOrders.Count - 1].CreatedOn) / row.count;
public List<ReportVM> DelayReasonAverage()
{
    return (from DelayReason dr in _delayReasons
            let row = new
            {
                delayId = dr.Id,
                delayTitle = dr.Title,
                workOrders = dr.WorkOrders.ToList(),
                count = _delayReasons.Count()
            }
            orderby row.count descending
            let reportObj = new ReportVM()
            {
                DelayTitle = row.delayTitle,
                Count = (int)Math.Round(row.workOrders[0].CreatedOn.DiffDays
                (row.workOrders[row.workOrders.Count - 1].CreatedOn) / (double)row.count)
            }
            select reportObj).ToList();
}

Context

StackExchange Code Review Q#162102, answer score: 2

Revisions (0)

No revisions yet.